scrapy+selenium爬取淘寶商品信息

本文僅作經驗分享,不做商業用途,如涉及權利問題,請通知刪除。

建立scrapy項目

scrapy和selenium是爬蟲常用的手段,現在我們開始新建個scrapy項目。

scrapy startproject taobao_s
cd taobao_s
scrapy genspider taobao s.taobao.com

建立一個taobao_s項目,在生成個spider taobao
生成項目結構如下
在這裏插入圖片描述

對目標網站進行分析

淘寶網反爬機制做的很全面,所以要爬取它要有一定條件。
首先淘寶網有個鏈接http://s.taobao.com/search?q=,這個鏈接能夠不需要登錄進行查詢內容,但是我們爬蟲時可能會被識別出來,所以我們應該嘗試模擬登錄淘寶保存cookie然後進行查詢,這裏我們模擬登錄利用的是最近的辦法,利用微博賬號進行登錄。接下來我們就進行selenium模擬登錄。

selenium模擬登錄

淘寶登陸頁面https://login.taobao.com/member/login.jhtml
現在模擬登錄常用的方法有支付寶賬號登錄(偶有滑塊驗證)、掃碼登陸(最麻瓜的)、微博賬號登陸(偶有驗證碼)本文利用的是微博賬號進行登陸。
打開瀏覽器,進入頁面,定位密碼登陸,定位微博登陸,然後進行模擬登陸,值得一提的是同一賬號登陸多次就會有驗證碼生成,建議多準備一些賬號或者是加入輸入驗證碼邏輯(窮學生用不起打碼平臺)登陸完成後利用get_cookies()來獲取cookie保存下來,以下是登陸的代碼

    def loginTaobao():
        url = 'https://login.taobao.com/member/login.jhtml'
        options = webdriver.ChromeOptions()
        # 不加載圖片,加快訪問速度
        # options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})
        # 此步驟很重要,設置爲開發者模式,防止被各大網站識別出來使用了Selenium
        options.add_experimental_option('excludeSwitches', ['enable-automation'])
        # options.add_argument('--headless')
        browser = webdriver.Chrome(executable_path="G:\chromedriver_win32\chromedriver.exe", options=options)
        wait = WebDriverWait(browser, 10)  # 超時時長爲10s
        # 打開網頁
        browser.get(url)
        # 自適應等待,點擊密碼登錄選項
        browser.implicitly_wait(30)  # 智能等待,直到網頁加載完畢,最長等待時間爲30s
        browser.find_element_by_xpath('//*[@class="forget-pwd J_Quick2Static"]').click()
        browser.find_element_by_xpath('//*[@class="weibo-login"]').click()
        browser.find_element_by_name('username').send_keys('微博賬號')
        browser.find_element_by_name('password').send_keys('微博密碼')
        browser.find_element_by_xpath('//*[@class="btn_tip"]/a/span').click()
       
        # 直到獲取到淘寶會員暱稱才能確定是登錄成功
        taobao_name = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,
                                                                      '.site-nav-bd > ul.site-nav-bd-l > li#J_SiteNavLogin > div.site-nav-menu-hd > div.site-nav-user > a.site-nav-login-info-nick ')))
        # 輸出淘寶暱稱
        print(taobao_name.text)

        cookies = browser.get_cookies()  
        browser.close()  # 獲取cookies便可以關閉瀏覽器
        # 然後的關鍵就是保存cookies,之後請求從文件中讀取cookies就可以省去每次都要登錄一次的
        jsonCookies = json.dumps(cookies)  # 通過json將cookies寫入文件
        with open('taobaoCookies.json', 'w') as f:
            f.write(jsonCookies)
        print(cookies)

發起請求

一般建立scrapy項目會利用start_urls來發起請求,但是我們自己做的話還是利用start_requests來做居多。註釋掉start_urls,編寫start_requests的邏輯。
https://s.taobao.com/search?q=%s&sort=sale-desc&s=%s
這裏用%s代表了一個搜索的內容;一個代表商品個數,淘寶的信息是以44個商品一頁的,也就是換成45的話就是第二頁了。這裏我們可以用range構造一下後面這個參數。
在settings中定義三個參數

KEY_WORDS = “拖鞋 男” #搜索詞
PAGE_NUM = 10 #頁數
ONE_PAGE_COUNT = 44 #每頁個數

    def start_requests(self):
        if not Path('taobaoCookies.json').exists():
            __class__.loginTaobao()  # 先執行login,保存cookies之後便可以免登錄操作
        # 從文件中獲取保存的cookies
        with open('taobaoCookies.json', 'r', encoding='utf-8') as f:
            listcookies = json.loads(f.read())  # 獲取cookies
        # 把獲取的cookies處理成dict類型
        cookies_dict = dict()
        for cookie in listcookies:
            # 在保存成dict時,我們其實只要cookies中的name和value,而domain等其他都可以不要
            cookies_dict[cookie['name']] = cookie['value']
        key_words = self.settings['KEY_WORDS']
        key_words = parse.quote(key_words).replace(' ', '+')
        print(key_words)
        page_num = self.settings['PAGE_NUM']
        one_page_num = self.settings['ONE_PAGE_COUNT']
        for i in range(page_num):
            url = self.base_url % (key_words, i*one_page_num)
            yield scrapy.Request(url, cookies=cookies_dict, callback=self.parse, headers=__class__.headers)

獲取數據

一般來說我們都是在parse來獲取response裏的各種數據的,也有可能會爬取多次,再跳轉到詳情頁內抓取評論parseNext(之後打算繼續做),在用parse之前我們要先準備item

class TaobaoSItem(scrapy.Item):
    # define the fields for your item here like:
    price = scrapy.Field()
    sales = scrapy.Field()
    title = scrapy.Field()
    nick = scrapy.Field()
    loc = scrapy.Field()
    detail_url = scrapy.Field()
    nid = scrapy.Field()
    sellerid = scrapy.Field()

定義好item後就寫傳值邏輯了,我們抓取可以利用xpath定位來拿,也可以用re來定位,而我這裏是利用re從js裏拿數據
在這裏插入圖片描述

    def parse(self, response):
        p = 'g_page_config = ({.*?});'
        g_page_config = response.selector.re(p)[0]
        g_page_config = json.loads(g_page_config)
        auctions = g_page_config['mods']['itemlist']['data']['auctions']
        url1 = 'https://rate.tmall.com/list_detail_rate.htm?itemId=%s&sellerId=%s&order=3&currentPage=%s'
        # 從文件中獲取保存的cookies
        with open('taobaoCookies.json', 'r', encoding='utf-8') as f:
            listcookies = json.loads(f.read())  # 獲取cookies
        # 把獲取的cookies處理成dict類型
        cookies_dict = dict()
        for cookie in listcookies:
            # 在保存成dict時,我們其實只要cookies中的name和value,而domain等其他都可以不要
            cookies_dict[cookie['name']] = cookie['value']
        for auction in auctions:
            item = TaobaoSItem()
            item['price'] = auction['view_price']
            item['sales'] = auction['view_sales']
            item['title'] = auction['raw_title']
            item['nick'] = auction['nick']
            item['loc'] = auction['item_loc']
            item['detail_url'] = auction['detail_url']
            item['nid'] = auction['nid']
            item['sellerid'] = auction['user_id']
            yield item

保存數據

這個憑藉個人喜好吧,可以存json、csv或者存入數據庫mongodb、redis之類的。但是最好把保存數據的邏輯放在管道Pipelines裏,當然我之前那個登陸其實放在中間件裏更好
這裏我是保存到mongoDB

import pymongo
class TaobaoSPipeline(object):

    def open_spider(self,spider):
        client = pymongo.MongoClient(host='127.0.0.1', port=27017)
        db = client['taobao']
        self.q = db['product']

    def process_item(self, item, spider):
        self.q.update({'nid': item['nid']}, {'$set': dict(item)}, True)
        return item

跑一下就可以拿到數據了
在這裏插入圖片描述
項目源碼
以上也是我初次用scrapy爬取,以往request+selenium就行了,如果有問題,可以與我交流。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章