[Python3]selenium爬取淘寶商品資訊

jerrysun發表於2021-09-09

前言

前面介紹了使用selenium和chromedriver透過模擬瀏覽器執行的方式可以做到在瀏覽器中看到是什麼樣,抓取的原始碼就是什麼樣。不用再去管網頁內部的JavaScript是如何渲染頁面,也不用管網頁後臺的Ajax介面有哪些引數,甚至是加密規律等。這篇部落格是實戰演練,透過Selenium爬取淘寶網商品的圖片,名稱,價格,購買人數,店鋪名稱,店鋪所在地資訊,將結果儲存至Mongodb資料庫中。

Chromedriver for linux

上一篇部落格只介紹了chromedriver在windows下的安裝

對應版本的下載和測試安裝是方法是一樣的

//解壓unzip chromedriver_linux64.zip//移動到環境變數所在的目錄sudo mv chromedriver /usr/bin//或者將chromedriver所在目錄,新增到環境變數export PATH="$PATH:所在目錄"//執行新的配置source ~/.porfile

分析一波

1.ajax請求分析

圖片描述

pic1

_ksTS,rn這兩個引數很難發現其規律,所以這裡不採用構造Ajax請求的方式來爬取內容,而透過selemium價格網頁最終呈現效果的HTML程式碼全部爬取下來,再來提取所要資訊

2.商品分析


圖片描述

pic2


需要說明的是srcdata-src都是商品圖片的網路地址,區別是前者是縮圖而後者是高畫質大圖,兩者都可以任意爬取,這裡爬取的是後者


3.頁碼分析

圖片描述

pic3

這裡不點選下一頁,而是透過自動輸入頁面數來進行頁面跳轉,一方面是要實時監控爬取到多少頁,另一方面,當程式出現異常,下一次執行又從第一頁開始,下一頁依次爬取,資料庫中,會有重複記錄

code

1. 獲取商品列表
import pymongofrom selenium import webdriverfrom selenium.common.exceptions import  TimeoutExceptionfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.support.wait import WebDriverWaitfrom urllib.parse import quotefrom pyquery import  PyQuery as pq

driver = webdriver.Chrome()
wait = WebDriverWait(driver,10)


KEYWORD = 'iMac'def index_page(page):
    print('正在爬取第',page,'頁')    try:
        url = ''+quote(KEYWORD)
        driver.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.presence_of_element_located((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)

透過構造查詢引數,得到淘寶網的搜尋URL,q後面接你要搜尋的關鍵詞。就能夠跳轉到搜尋指定商品後的頁面,也是程式的入口URL
透過改變EYWORD的值,就能爬取不同商品資訊;拼接URL的時候用到quote方法,遮蔽特殊字串,如空格等,URL地址裡是不含空格的,同時將字串轉換為URL編碼格式,以保證URL的正確性。

下面程式碼等待載入時,使用了WebDriverWait物件,指定等待條件和10s的最長等待時間,如果在這個時間內頁面元素成功載入出來了,就相應結果並繼續向下執行,否則丟擲超時異常。EC.presence_of_element_located是元素成功載入出來,EC.presence_of_element_located 意思是元素可以點選,因為它是一個按鈕,這個按鈕的作用是選定頁碼後的點選確定後跳轉。

為了驗證跳轉到了對應的頁碼,需要判斷當前高亮的頁碼數是當前的頁碼數(當前所在頁碼會高亮顯示,也就是說當前頁碼的css是特殊的),所以這裡使用了另一個等待條件text_to_be_present_in_element,它會等待指定的文字出現在某一個節點裡面時即返回成功。這裡我們將高亮的頁碼節點對應的CSS選擇器和當前要跳轉的頁碼透過引數傳遞給這個等待條件,這樣它就會檢測當前高亮的頁碼節點是不是我們傳過來的頁碼數,如果是,就證明頁面成功跳轉到了這一頁,頁面跳轉成功。

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

這些等待條件的引數都是特定的css選擇器,不做贅述了,圖片已經標註的很清楚了

2.解析商品列表
def get_products():
    html = driver.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)
        print('n')

透過driver.page_source 獲得了不同頁碼下完整html原始碼;同時使用Pyqurey來解析網頁,透過已經查詢的標籤,查詢這個標籤下的子標籤或者父標籤,而不用從頭開始查詢,效率更高;透過find(css).屬性方法,獲取圖片URL,和其他文字資訊並構造成Json字串,呼叫save_to_mongo函式存入資料庫中。

3.將結果儲存到Mogodb中
def save_to_mongo(result):
    client = pymongo.MongoClient('mongodb://admin:admin123@localhost:27017/')
    db = client['taobao']
    collection = db['products']    try:        if collection.insert(result):
            print("成功儲存到MongoDB")    except Exception:
        print('someing wrong with MongDB')

python3透過認證方式連線Mongodb資料庫,admin是我的使用者名稱,admin123是我的密碼,接著指定資料庫和集合,呼叫insert方法插入資料。

4.定義爬取頁數
def main():
    MAX_PAGE = 100
    for i in range(1,MAX_PAGE+1):
        index_page(i)
    driver.close()if __name__ =='__main__':
    main()

簡單for迴圈,並透過range生成1到100的數傳遞給index_page函式。

5.完整程式碼
import pymongofrom selenium import webdriverfrom selenium.common.exceptions import  TimeoutExceptionfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.support.wait import WebDriverWaitfrom urllib.parse import quotefrom pyquery import  PyQuery as pq

driver = webdriver.Chrome()
wait = WebDriverWait(driver,10)


KEYWORD = 'iMac'def index_page(page):
    print('正在爬取第',page,'頁')    try:
        url = ''+quote(KEYWORD)
        driver.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)def get_products():
    html = driver.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)
        print('n')def save_to_mongo(result):
    client = pymongo.MongoClient('mongodb://admin:admin123@localhost:27017/')
    db = client['taobao']
    collection = db['products']    try:        if collection.insert(result):
            print("成功儲存到MongoDB")    except Exception:
        print('someing wrong with MongDB')
        

MAX_PAGE = 100def main():
    for i in range(1,MAX_PAGE+1):
        index_page(i)
    driver.close()if __name__ =='__main__':
    main()

小結

這段程式是對以前所學知識的綜合利用,Mongodb是前幾天現學現用,這是我第一次使用,關係型資料庫Oracle,Sql server,Mysql都用過,基本知識也有掌握,非關係型資料庫
Mongodb以後可能會寫幾篇學習筆記

執行結果

1,輸出結果

圖片描述

pic4

2.檢視mongodb中存入的資料

圖片描述

pic5



作者:留心的話沒有小事
連結:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/151/viewspace-2816901/,如需轉載,請註明出處,否則將追究法律責任。

相關文章