欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

【Python3網絡爬蟲開發實戰】7.4-使用Selenium爬取淘寶商品

系統 1616 0

【摘要】 在前一章中,我們已經成功嘗試分析Ajax來抓取相關數據,但是并不是所有頁面都可以通過分析Ajax來完成抓取。比如,淘寶,它的整個頁面數據確實也是通過Ajax獲取的,但是這些Ajax接口參數比較復雜,可能會包含加密密鑰等,所以如果想自己構造Ajax參數,還是比較困難的。對于這種頁面,最方便快捷的抓取方法就是通過Selenium。

本節中,我們就用Selenium來模擬瀏覽器操作,抓取淘寶的商品信息,并將結果保存到MongoDB。

1. 本節目標

本節中,我們要利用Selenium抓取淘寶商品并用pyquery解析得到商品的圖片、名稱、價格、購買人數、店鋪名稱和店鋪所在地信息,并將其保存到MongoDB。

2. 準備工作

本節中,我們首先以Chrome為例來講解Selenium的用法。在開始之前,請確保已經正確安裝好Chrome瀏覽器并配置好了ChromeDriver;另外,還需要正確安裝Python的Selenium庫;最后,還對接了PhantomJS和Firefox,請確保安裝好PhantomJS和Firefox并配置好了GeckoDriver。如果環境沒有配置好,可參考第1章。

3. 接口分析

首先,我們來看下淘寶的接口,看看它比一般Ajax多了怎樣的內容。

打開淘寶頁面,搜索商品,比如iPad,此時打開開發者工具,截獲Ajax請求,我們可以發現獲取商品列表的接口,如圖7-19所示。

【Python3網絡爬蟲開發實戰】7.4-使用Selenium爬取淘寶商品_第1張圖片

圖7-19 列表接口

它的鏈接包含了幾個GET參數,如果要想構造Ajax鏈接,直接請求再好不過了,它的返回內容是JSON格式,如圖7-20所示。

【Python3網絡爬蟲開發實戰】7.4-使用Selenium爬取淘寶商品_第2張圖片

圖7-20 JSON數據

但是這個Ajax接口包含幾個參數,其中_ksTS、rn參數不能直接發現其規律,如果要去探尋它的生成規律,也不是做不到,但這樣相對會比較煩瑣,所以如果直接用Selenium來模擬瀏覽器的話,就不需要再關注這些接口參數了,只要在瀏覽器里面可以看到的,都可以爬取。這也是我們選用Selenium爬取淘寶的原因。

4. 頁面分析

本節的目標是爬取商品信息。圖7-21是一個商品條目,其中包含商品的基本信息,包括商品圖片、名稱、價格、購買人數、店鋪名稱和店鋪所在地,我們要做的就是將這些信息都抓取下來。

【Python3網絡爬蟲開發實戰】7.4-使用Selenium爬取淘寶商品_第3張圖片

圖7-21 商品條目

抓取入口就是淘寶的搜索頁面,這個鏈接可以通過直接構造參數訪問。例如,如果搜索iPad,就可以直接訪問https://s.taobao.com/search?q=iPad,呈現的就是第一頁的搜索結果,如圖7-22所示。

【Python3網絡爬蟲開發實戰】7.4-使用Selenium爬取淘寶商品_第4張圖片

圖7-22 搜索結果

在頁面下方,有一個分頁導航,其中既包括前5頁的鏈接,也包括下一頁的鏈接,同時還有一個輸入任意頁碼跳轉的鏈接,如圖7-23所示。

7-23-1.jpg

圖7-23 分頁導航

這里商品的搜索結果一般最大都為100頁,要獲取每一頁的內容,只需要將頁碼從1到100順序遍歷即可,頁碼數是確定的。所以,直接在頁面跳轉文本框中輸入要跳轉的頁碼,然后點擊“確定”按鈕即可跳轉到頁碼對應的頁面。

這里不直接點擊“下一頁”的原因是:一旦爬取過程中出現異常退出,比如到50頁退出了,此時點擊“下一頁”時,就無法快速切換到對應的后續頁面了。此外,在爬取過程中,也需要記錄當前的頁碼數,而且一旦點擊“下一頁”之后頁面加載失敗,還需要做異常檢測,檢測當前頁面是加載到了第幾頁。整個流程相對比較復雜,所以這里我們直接用跳轉的方式來爬取頁面。

當我們成功加載出某一頁商品列表時,利用Selenium即可獲取頁面源代碼,然后再用相應的解析庫解析即可。這里我們選用pyquery進行解析。下面我們用代碼來實現整個抓取過程。

5. 獲取商品列表

首先,需要構造一個抓取的URL:https://s.taobao.com/search?q=iPad。這個URL非常簡潔,參數q就是要搜索的關鍵字。只要改變這個參數,即可獲取不同商品的列表。這里我們將商品的關鍵字定義成一個變量,然后構造出這樣的一個URL。

然后,就需要用Selenium進行抓取了。我們實現如下抓取列表頁的方法:

            
              from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from urllib.parse import quote

browser = webdriver.Chrome()
wait = WebDriverWait(browser, 10)
KEYWORD = 'iPad'

def index_page(page):
    """
    抓取索引頁
    :param page: 頁碼
    """
    print('正在爬取第', page, '頁')
    try:
        url = 'https://s.taobao.com/search?q=' + quote(KEYWORD)
        browser.get(url)
        if page > 1:
            input = wait.until(
                EC.presence_of_element_located((By.CSS_SELECTOR, '#mainsrp-pager div.form > input')))
            submit = wait.until(
                EC.element_to_be_clickable((By.CSS_SELECTOR, '#mainsrp-pager div.form > span.btn.J_Submit')))
            input.clear()
            input.send_keys(page)
            submit.click()
        wait.until(
            EC.text_to_be_present_in_element((By.CSS_SELECTOR, '#mainsrp-pager li.item.active > span'), str(page)))
        wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.m-itemlist .items .item')))
        get_products()
    except TimeoutException:
        index_page(page)
            
          

這里首先構造了一個WebDriver對象,使用的瀏覽器是Chrome,然后指定一個關鍵詞,如iPad,接著定義了index_page()方法,用于抓取商品列表頁。

在該方法里,我們首先訪問了搜索商品的鏈接,然后判斷了當前的頁碼,如果大于1,就進行跳頁操作,否則等待頁面加載完成。

等待加載時,我們使用了WebDriverWait對象,它可以指定等待條件,同時指定一個最長等待時間,這里指定為最長10秒。如果在這個時間內成功匹配了等待條件,也就是說頁面元素成功加載出來了,就立即返回相應結果并繼續向下執行,否則到了最大等待時間還沒有加載出來時,就直接拋出超時異常。

比如,我們最終要等待商品信息加載出來,就指定了presence_of_element_located這個條件,然后傳入了.m-itemlist .items .item這個選擇器,而這個選擇器對應的頁面內容就是每個商品的信息塊,可以到網頁里面查看一下。如果加載成功,就會執行后續的get_products()方法,提取商品信息。

關于翻頁操作,這里首先獲取頁碼輸入框,賦值為input,然后獲取“確定”按鈕,賦值為submit,分別是圖7-24中的兩個元素。

7-24-1.jpg

圖7-24 跳轉選項

首先,我們清空了輸入框,此時調用clear()方法即可。隨后,調用send_keys()方法將頁碼填充到輸入框中,然后點擊“確定”按鈕即可。

那么,怎樣知道有沒有跳轉到對應的頁碼呢?我們可以注意到,成功跳轉某一頁后,頁碼都會高亮顯示,如圖7-25所示。

7-25-1.jpg

圖7-25 頁碼高亮顯示

我們只需要判斷當前高亮的頁碼數是當前的頁碼數即可,所以這里使用了另一個等待條件text_to_be_present_in_element,它會等待指定的文本出現在某一個節點里面時即返回成功。這里我們將高亮的頁碼節點對應的CSS選擇器和當前要跳轉的頁碼通過參數傳遞給這個等待條件,這樣它就會檢測當前高亮的頁碼節點是不是我們傳過來的頁碼數,如果是,就證明頁面成功跳轉到了這一頁,頁面跳轉成功。

這樣剛才實現的index_page()方法就可以傳入對應的頁碼,待加載出對應頁碼的商品列表后,再去調用get_products()方法進行頁面解析。

6. 解析商品列表

接下來,我們就可以實現get_products()方法來解析商品列表了。這里我們直接獲取頁面源代碼,然后用pyquery進行解析,實現如下:

            
              from pyquery import PyQuery as pq
def get_products():
    """
    提取商品數據
    """
    html = browser.page_source
    doc = pq(html)
    items = doc('#mainsrp-itemlist .items .item').items()
    for item in items:
        product = {
            'image': item.find('.pic .img').attr('data-src'),
            'price': item.find('.price').text(),
            'deal': item.find('.deal-cnt').text(),
            'title': item.find('.title').text(),
            'shop': item.find('.shop').text(),
            'location': item.find('.location').text()
        }
        print(product)
        save_to_mongo(product)
            
          

首先,調用page_source屬性獲取頁碼的源代碼,然后構造了PyQuery解析對象,接著提取了商品列表,此時使用的CSS選擇器是#mainsrp-itemlist .items .item,它會匹配整個頁面的每個商品。它的匹配結果是多個,所以這里我們又對它進行了一次遍歷,用for循環將每個結果分別進行解析,每次循環把它賦值為item變量,每個item變量都是一個PyQuery對象,然后再調用它的find()方法,傳入CSS選擇器,就可以獲取單個商品的特定內容了。

比如,查看一下商品信息的源碼,如圖7-26所示。

【Python3網絡爬蟲開發實戰】7.4-使用Selenium爬取淘寶商品_第5張圖片

圖7-26 商品信息源碼

可以發現,它是一個img節點,包含id、class、data-src、alt和src等屬性。這里之所以可以看到這張圖片,是因為它的src屬性被賦值為圖片的URL。把它的src屬性提取出來,就可以獲取商品的圖片了。不過我們還注意data-src屬性,它的內容也是圖片的URL,觀察后發現此URL是圖片的完整大圖,而src是壓縮后的小圖,所以這里抓取data-src屬性來作為商品的圖片。

因此,我們需要先利用find()方法找到圖片的這個節點,然后再調用attr()方法獲取商品的data-src屬性,這樣就成功提取了商品圖片鏈接。然后用同樣的方法提取商品的價格、成交量、名稱、店鋪和店鋪所在地等信息,接著將所有提取結果賦值為一個字典product,隨后調用save_to_mongo()將其保存到MongoDB即可。

7. 保存到MongoDB

接下來,我們將商品信息保存到MongoDB,實現代碼如下:

            
              MONGO_URL = 'localhost'
MONGO_DB = 'taobao'
MONGO_COLLECTION = 'products'
client = pymongo.MongoClient(MONGO_URL)
db = client[MONGO_DB]
def save_to_mongo(result):
    """
    保存至MongoDB
    :param result: 結果
    """
    try:
        if db[MONGO_COLLECTION].insert(result):
            print('存儲到MongoDB成功')
    except Exception:
        print('存儲到MongoDB失敗')
            
          

這里首先創建了一個MongoDB的連接對象,然后指定了數據庫,隨后指定了Collection的名稱,接著直接調用insert()方法將數據插入到MongoDB。此處的result變量就是在get_products()方法里傳來的product,包含單個商品的信息。

8. 遍歷每頁

剛才我們所定義的get_index()方法需要接收參數page,page代表頁碼。這里我們實現頁碼遍歷即可,代碼如下:

            
              MAX_PAGE = 100
def main():
    """
    遍歷每一頁
    """
    for i in range(1, MAX_PAGE + 1):
        index_page(i)
            
          

其實現非常簡單,只需要調用一個for循環即可。這里定義最大的頁碼數為100,range()方法的返回結果就是1到100的列表,順序遍歷,調用index_page()方法即可。

這樣我們的淘寶商品爬蟲就完成了,最后調用main()方法即可運行。

9. 運行

運行代碼,可以發現首先會彈出一個Chrome瀏覽器,然后會訪問淘寶頁面,接著控制臺便會輸出相應的提取結果,如圖7-27所示。

【Python3網絡爬蟲開發實戰】7.4-使用Selenium爬取淘寶商品_第6張圖片

圖7-27 運行結果

可以發現,這些商品信息的結果都是字典形式,它們被存儲到MongoDB里面。

再看一下MongoDB中的結果,如圖7-28所示。

【Python3網絡爬蟲開發實戰】7.4-使用Selenium爬取淘寶商品_第7張圖片

圖7-28 保存結果

可以看到,所有的信息都保存到MongoDB里了,這說明爬取成功。

10. Chrome Headless模式

從Chrome 59版本開始,已經開始支持Headless模式,也就是無界面模式,這樣爬取的時候就不會彈出瀏覽器了。如果要使用此模式,請把Chrome升級到59版本及以上。啟用Headless模式的方式如下:

            
              chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
browser = webdriver.Chrome(chrome_options=chrome_options)
            
          

首先,創建ChromeOptions對象,接著添加headless參數,然后在初始化Chrome對象的時候通過chrome_options傳遞這個ChromeOptions對象,這樣我們就可以成功啟用Chrome的Headless模式了。

11. 對接Firefox

要對接Firefox瀏覽器,非常簡單,只需要更改一處即可:

            
              browser = webdriver.Firefox()
            
          

這里更改了browser對象的創建方式,這樣爬取的時候就會使用Firefox瀏覽器了。

12. 對接PhantomJS

如果不想使用Chrome的Headless模式,還可以使用PhantomJS(它是一個無界面瀏覽器)來抓取。抓取時,同樣不會彈出窗口,還是只需要將WebDriver的聲明修改一下即可:

            
              browser = webdriver.PhantomJS()
            
          

另外,它還支持命令行配置。比如,可以設置緩存和禁用圖片加載的功能,進一步提高爬取效率:

            
              SERVICE_ARGS = ['--load-images=false', '--disk-cache=true']
browser = webdriver.PhantomJS(service_args=SERVICE_ARGS)
            
          

最后,給出本節的代碼地址:https://github.com/Python3WebSpider/TaobaoProduct。

本節中,我們用Selenium演示了淘寶頁面的抓取。利用它,我們不用去分析Ajax請求,真正做到可見即可爬。

來源:華為云社區 ?作者:崔慶才丨靜覓

?


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 一区二区三区杨幂在线观看 | 91精品观看91久久久久久 | 色老头xxxwww作爱视频 | 亚洲一区中文字幕 | 日韩一区二区三区视频 | 无码国产精品成人午夜视频 | 国产aaaaa一级毛片 | 免费看黄色一级大片 | 欧美精品在线不卡 | 免费看黄色一级大片 | 国产免费播放一区二区 | 日韩欧美在线免费观看视频 | 91视频视频 | 污视频网页 | 久久久久亚洲精品 | 老版亮剑50集免费观看 | 久久久久久久国产 | 末成年毛片在线播放 | 精品一区二区三区四区 | 国产精品v欧美精品v日韩精品 | 天天爽天天干天天操 | 国产欧美日韩不卡一区二区三区 | 日本女人毛茸茸 | 亚洲日韩视频 | 成年视频在线观看免费 | 国产一级毛片在线看 | 久久99精品久久久97夜夜嗨 | 高清一区在线 | 91免费精品国偷自产在线在线 | 色播在线永久免费视频网站 | 国产精品人妻无码久久久2022 | 91免费无限观看 | 永久免费mv网站入口 | 三级视频在线播放 | 91青青草视频 | videosex久久麻豆 | 在线色网站 | 九九热中文字幕 | 婷婷色综合久久五月亚洲 | 少妇的肉体的满足毛片 | 韩国精品 |