[Python3]selenium爬取淘寶商品信息

前言

前面介紹了使用selenium和chromedriver通過模擬瀏覽器運行的方式可以做到在瀏覽器中看到是什么樣,抓取的源碼就是什么樣。不用再去管網(wǎng)頁內(nèi)部的JavaScript是如何渲染頁面,也不用管網(wǎng)頁后臺的Ajax接口有哪些參數(shù),甚至是加密規(guī)律等。這篇博客是實戰(zhàn)演練,通過Selenium爬取淘寶網(wǎng)商品的圖片,名稱,價格,購買人數(shù),店鋪名稱,店鋪所在地信息,將結(jié)果保存至Mongodb數(shù)據(jù)庫中。

Chromedriver for linux

上一篇博客只介紹了chromedriver在windows下的安裝

http://yhch.xyz/2018/07/08/Python3%E7%88%AC%E8%99%AB-selenium-chromedriver%E5%8F%AF%E8%A7%81%E5%8D%B3%E5%8F%AF%E7%88%AC/

對應(yīng)版本的下載和測試安裝是方法是一樣的

//解壓
unzip chromedriver_linux64.zip
//移動到環(huán)境變量所在的目錄
sudo mv chromedriver /usr/bin

//或者將chromedriver所在目錄,添加到環(huán)境變量
export PATH="$PATH:所在目錄"
//執(zhí)行新的配置
source ~/.porfile

分析一波

1.ajax請求分析
pic1

_ksTS,rn這兩個參數(shù)很難發(fā)現(xiàn)其規(guī)律,所以這里不采用構(gòu)造Ajax請求的方式來爬取內(nèi)容,而通過selemium價格網(wǎng)頁最終呈現(xiàn)效果的HTML代碼全部爬取下來,再來提取所要信息

2.商品分析

pic2

需要說明的是srcdata-src都是商品圖片的網(wǎng)絡(luò)地址,區(qū)別是前者是縮略圖而后者是高清大圖,兩者都可以任意爬取,這里爬取的是后者

3.頁碼分析

pic3

這里不點擊下一頁,而是通過自動輸入頁面數(shù)來進行頁面跳轉(zhuǎn),一方面是要實時監(jiān)控爬取到多少頁,另一方面,當(dāng)程序出現(xiàn)異常,下一次運行又從第一頁開始,下一頁依次爬取,數(shù)據(jù)庫中,會有重復(fù)記錄

code

1. 獲取商品列表
import pymongo
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
from pyquery import  PyQuery as pq

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


KEYWORD = 'iMac'

def index_page(page):
    print('正在爬取第',page,'頁')
    try:
        url = 'https://s.taobao.com/search?q='+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)

通過構(gòu)造查詢參數(shù),得到淘寶網(wǎng)的搜索URLhttps://s.taobao.com/search?q=iMac,q后面接你要搜索的關(guān)鍵詞。就能夠跳轉(zhuǎn)到搜索指定商品后的頁面,也是程序的入口URL
通過改變EYWORD的值,就能爬取不同商品信息;拼接URL的時候用到quote方法,屏蔽特殊字符串,如空格等,URL地址里是不含空格的,同時將字符串轉(zhuǎn)換為URL編碼格式,以保證URL的正確性。

下面代碼等待加載時,使用了WebDriverWait對象,指定等待條件和10s的最長等待時間,如果在這個時間內(nèi)頁面元素成功加載出來了,就相應(yīng)結(jié)果并繼續(xù)向下執(zhí)行,否則拋出超時異常。EC.presence_of_element_located是元素成功加載出來,EC.presence_of_element_located 意思是元素可以點擊,因為它是一個按鈕,這個按鈕的作用是選定頁碼后的點擊確定后跳轉(zhuǎn)。

為了驗證跳轉(zhuǎn)到了對應(yīng)的頁碼,需要判斷當(dāng)前高亮的頁碼數(shù)是當(dāng)前的頁碼數(shù)(當(dāng)前所在頁碼會高亮顯示,也就是說當(dāng)前頁碼的css是特殊的),所以這里使用了另一個等待條件text_to_be_present_in_element,它會等待指定的文本出現(xiàn)在某一個節(jié)點里面時即返回成功。這里我們將高亮的頁碼節(jié)點對應(yīng)的CSS選擇器和當(dāng)前要跳轉(zhuǎn)的頁碼通過參數(shù)傳遞給這個等待條件,這樣它就會檢測當(dāng)前高亮的頁碼節(jié)點是不是我們傳過來的頁碼數(shù),如果是,就證明頁面成功跳轉(zhuǎn)到了這一頁,頁面跳轉(zhuǎn)成功。

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

這些等待條件的參數(shù)都是特定的css選擇器,不做贅述了,圖片已經(jīng)標(biāo)注的很清楚了

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來解析網(wǎng)頁,通過已經(jīng)查找的標(biāo)簽,查找這個標(biāo)簽下的子標(biāo)簽或者父標(biāo)簽,而不用從頭開始查找,效率更高;通過find(css).屬性方法,獲取圖片URL,和其他文本信息并構(gòu)造成Json字符串,調(diào)用save_to_mongo函數(shù)存入數(shù)據(jù)庫中。

3.將結(jié)果保存到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通過認(rèn)證方式連接Mongodb數(shù)據(jù)庫,admin是我的用戶名,admin123是我的密碼,接著指定數(shù)據(jù)庫和集合,調(diào)用insert方法插入數(shù)據(jù)。

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

if __name__ =='__main__':
    main()

簡單for循環(huán),并通過range生成1到100的數(shù)傳遞給index_page函數(shù)。

5.完整代碼
import pymongo
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
from pyquery import  PyQuery as pq

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


KEYWORD = 'iMac'

def index_page(page):
    print('正在爬取第',page,'頁')
    try:
        url = 'https://s.taobao.com/search?q='+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 = 100
def main():
    for i in range(1,MAX_PAGE+1):
        index_page(i)
    driver.close()


if __name__ =='__main__':
    main()    

小結(jié)

這段程序是對以前所學(xué)知識的綜合利用,Mongodb是前幾天現(xiàn)學(xué)現(xiàn)用,這是我第一次使用,關(guān)系型數(shù)據(jù)庫Oracle,Sql server,Mysql都用過,基本知識也有掌握,非關(guān)系型數(shù)據(jù)庫
Mongodb以后可能會寫幾篇學(xué)習(xí)筆記

運行結(jié)果

1,輸出結(jié)果
pic4
2.查看mongodb中存入的數(shù)據(jù)
pic5
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 32,303評論 2 89
  • 本文是我接觸爬蟲以來,第三套爬蟲的代碼記錄博客。本文主要是記錄淘寶搜索美食的頁面信息,工具是selenium 和 ...
    小白猿閱讀 1,156評論 1 9
  • 雖然淘寶的頁面數(shù)據(jù)是通過 Ajax 獲取的,也就是可以通過開發(fā)者模式直接找到它請求數(shù)據(jù)的接口,并且發(fā)現(xiàn)返回的數(shù)據(jù)是...
    小飛牛_666閱讀 1,041評論 0 11
  • http://opensource.apple.com/source/
    曲終人散Li閱讀 418評論 0 0
  • 昨天沒有聯(lián)系,心心念念想著裝修房子的事情,我以為自己專心投入一件事然后就可以將它遺忘,早晨起來思念泛濫,我一直壓抑...
    水底深藍(lán)閱讀 200評論 0 0

友情鏈接更多精彩內(nèi)容