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

前言

前面介紹了使用selenium和chromedriver通過模擬瀏覽器運(yùn)行的方式可以做到在瀏覽器中看到是什么樣浮梢,抓取的源碼就是什么樣。不用再去管網(wǎng)頁內(nèi)部的JavaScript是如何渲染頁面彤路,也不用管網(wǎng)頁后臺的Ajax接口有哪些參數(shù)秕硝,甚至是加密規(guī)律等。這篇博客是實(shí)戰(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

這里不點(diǎn)擊下一頁,而是通過自動輸入頁面數(shù)來進(jìn)行頁面跳轉(zhuǎn)昂灵,一方面是要實(shí)時監(jiān)控爬取到多少頁避凝,另一方面,當(dāng)程序出現(xiàn)異常眨补,下一次運(yù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 意思是元素可以點(diǎn)擊,因?yàn)樗且粋€按鈕咒彤,這個按鈕的作用是選定頁碼后的點(diǎn)擊確定后跳轉(zhuǎn)。

為了驗(yà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é)點(diǎn)里面時即返回成功模叙。這里我們將高亮的頁碼節(jié)點(diǎn)對應(yīng)的CSS選擇器和當(dāng)前要跳轉(zhuǎn)的頁碼通過參數(shù)傳遞給這個等待條件歇拆,這樣它就會檢測當(dāng)前高亮的頁碼節(jié)點(diǎn)是不是我們傳過來的頁碼數(shù),如果是范咨,就證明頁面成功跳轉(zhuǎn)到了這一頁故觅,頁面跳轉(zhuǎn)成功。

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

這些等待條件的參數(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í)筆記

運(yùn)行結(jié)果

1影所,輸出結(jié)果
pic4
2.查看mongodb中存入的數(shù)據(jù)
pic5
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市僚碎,隨后出現(xiàn)的幾起案子猴娩,更是在濱河造成了極大的恐慌,老刑警劉巖勺阐,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件卷中,死亡現(xiàn)場離奇詭異,居然都是意外死亡渊抽,警方通過查閱死者的電腦和手機(jī)蟆豫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來懒闷,“玉大人十减,你說我怎么就攤上這事》吖溃” “怎么了帮辟?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長玩焰。 經(jīng)常有香客問我由驹,道長,這世上最難降的妖魔是什么震捣? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任荔棉,我火速辦了婚禮,結(jié)果婚禮上蒿赢,老公的妹妹穿的比我還像新娘润樱。我一直安慰自己,他們只是感情好羡棵,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布壹若。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪店展。 梳的紋絲不亂的頭發(fā)上养篓,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天,我揣著相機(jī)與錄音赂蕴,去河邊找鬼柳弄。 笑死,一個胖子當(dāng)著我的面吹牛概说,可吹牛的內(nèi)容都是我干的碧注。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼糖赔,長吁一口氣:“原來是場噩夢啊……” “哼萍丐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起放典,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤逝变,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后奋构,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體壳影,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年弥臼,在試婚紗的時候發(fā)現(xiàn)自己被綠了态贤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡醋火,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出箱吕,到底是詐尸還是另有隱情芥驳,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布茬高,位于F島的核電站兆旬,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏怎栽。R本人自食惡果不足惜丽猬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望熏瞄。 院中可真熱鬧脚祟,春花似錦、人聲如沸强饮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至行您,卻和暖如春铭乾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背娃循。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工炕檩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人捌斧。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓笛质,卻偏偏與公主長得像,于是被迫代替她去往敵國和親骤星。 傳聞我的和親對象是個殘疾皇子经瓷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容