Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
私信小編01即可獲取大量Python學(xué)習(xí)資料
Tip:本文僅供學(xué)習(xí)與交流,切勿用于非法用途!!!
有個(gè)同學(xué)問(wèn)我:“XXX,有沒(méi)有辦法搜集一下淘寶的商品信息啊,我想要做個(gè)統(tǒng)計(jì)”。于是乎,閑來(lái)無(wú)事的我,又開始琢磨起這事…
俗話說(shuō),實(shí)踐出真知~
小的在這給大家安利一套《2020最新企業(yè)Pyhon項(xiàng)目實(shí)戰(zhàn)》視頻教程,點(diǎn)擊此處即可獲取,希望大家一起進(jìn)步哦。
興致勃勃的我,沖進(jìn)淘寶就準(zhǔn)備一頓亂搜:
在搜索欄里填好關(guān)鍵詞:“顯卡”,小手輕快敲擊著回車鍵(小樣~看我的)
心情愉悅的我等待著返回滿滿的商品信息,結(jié)果苦苦的等待換了的卻是302,于是我意外地來(lái)到了登陸界面。
情況基本就是這么個(gè)情況了…
然后我查了一下,隨著淘寶反爬手段的不斷加強(qiáng),很多小伙伴應(yīng)該已經(jīng)發(fā)現(xiàn),淘寶搜索功能是需要用戶登陸的!
關(guān)于淘寶模擬登陸,有大大已經(jīng)利用requests成功模擬登陸(感興趣的小伙伴請(qǐng)往這邊>>>requests登陸淘寶<<<)
這個(gè)方法得先分析淘寶登陸的各種請(qǐng)求,并模擬生成相應(yīng)的參數(shù),相對(duì)來(lái)說(shuō)有一定的難度。于是我決定換一種思路,通過(guò)selenium+二維碼的方式:
# 打開圖片
def Openimg(img_location):
img=Image.open(img_location)
img.show()
# 登陸獲取cookies
def Login():
driver=webdriver.PhantomJS()
driver.get('https://login.taobao.com/member/login.jhtml')
try:
driver.find_element_by_xpath('//*[@id="login"]/div[1]/i').click()
except:
pass
time.sleep(3)
# 執(zhí)行JS獲得canvas的二維碼
JS='return document.getElementsByTagName("canvas")[0].toDataURL("image/png");'
im_info=driver.execute_script(JS) # 執(zhí)行JS獲取圖片信息
im_base64=im_info.split(',')[1] #拿到base64編碼的圖片信息
im_bytes=base64.b64decode(im_base64) #轉(zhuǎn)為bytes類型
time.sleep(2)
with open('./login.png','wb') as f:
f.write(im_bytes)
f.close()
t=threading.Thread(target=Openimg,args=('./login.png',))
t.start()
print("Logining...Please sweep the code!\n")
while(True):
c=driver.get_cookies()
if len(c) > 20: #登陸成功獲取到cookies
cookies={}
for i in range(len(c)):
cookies[c[i]['name']]=c[i]['value']
driver.close()
print("Login in successfully!\n")
return cookies
time.sleep(1)
通過(guò)webdriver打開淘寶登陸界面,把二維碼下載到本地并打開等待用戶掃碼(相應(yīng)的元素大家通過(guò)瀏覽器的F12元素分析很容易就能找出)。待掃碼成功后,將webdriver里的cookies轉(zhuǎn)為DICT形式,并返回。(這里是為了后續(xù)requests爬取信息的時(shí)候使用)
當(dāng)我拿到cookies之后,便能對(duì)商品信息進(jìn)行爬取了。
(小樣 ~我來(lái)啦)
定義相應(yīng)的請(qǐng)求地址,請(qǐng)求頭等等:
# 定義參數(shù)
headers={'Host':'s.taobao.com',
'User-Agent':'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:63.0) Gecko/20100101 Firefox/63.0',
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language':'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Accept-Encoding':'gzip, deflate, br',
'Connection':'keep-alive'}
list_url='http://s.taobao.com/search?q=%(key)s&ie=utf8&s=%(page)d'
12345678
當(dāng)請(qǐng)求得到HTML頁(yè)面后,想要得到我們想要的數(shù)據(jù)就必須得對(duì)其進(jìn)行提取,這里我選擇了正則的方式。通過(guò)查看頁(yè)面源碼:
偷懶的我上面只標(biāo)志了兩個(gè)數(shù)據(jù),不過(guò)其他也是類似的,于是得到以下正則:
# 正則模式
p_title='"raw_title":"(.*?)"' #標(biāo)題
p_location='"item_loc":"(.*?)"' #銷售地
p_sale='"view_sales":"(.*?)人付款"' #銷售量
p_comment='"comment_count":"(.*?)"'#評(píng)論數(shù)
p_price='"view_price":"(.*?)"' #銷售價(jià)格
p_nid='"nid":"(.*?)"' #商品唯一ID
p_img='"pic_url":"(.*?)"' #圖片URL
12345678
(ps.聰明的小伙伴應(yīng)該已經(jīng)發(fā)現(xiàn)了,其實(shí)商品信息是被保存在了g_page_config變量里面,所以我們也可以先提取這個(gè)變量(一個(gè)字典),然后再讀取數(shù)據(jù),也可!)
完事具備,只欠東風(fēng)。于是,東風(fēng)來(lái)了:
# 數(shù)據(jù)爬取
key=input('請(qǐng)輸入關(guān)鍵字:') # 商品的關(guān)鍵詞
N=20 # 爬取的頁(yè)數(shù)
data=[]
cookies=Login()
for i in range(N):
try:
page=i*44
url=list_url%{'key':key,'page':page}
res=requests.get(url,headers=headers,cookies=cookies)
html=res.text
title=re.findall(p_title,html)
location=re.findall(p_location,html)
sale=re.findall(p_sale,html)
comment=re.findall(p_comment,html)
price=re.findall(p_price,html)
nid=re.findall(p_nid,html)
img=re.findall(p_img,html)
for j in range(len(title)):
data.append([title[j],location[j],sale[j],comment[j],price[j],nid[j],img[j]])
print('-------Page%s complete!--------\n\n'%(i+1))
time.sleep(3)
except:
pass
data=pd.DataFrame(data,columns=['title','location','sale','comment','price','nid','img'])
data.to_csv('%s.csv'%key,encoding='utf-8',index=False)
上面代碼爬取20也商品信息,并將其保存在本地的csv文件中,效果是這樣的:
有了數(shù)據(jù),放著豈不是浪費(fèi),我可是社會(huì)主義好青年,怎能做這種事? 那么,就讓我們來(lái)簡(jiǎn)單看看這些數(shù)據(jù)叭:
(當(dāng)然,數(shù)據(jù)量小,僅供娛樂(lè)參考)
# 導(dǎo)入相關(guān)庫(kù)
import jieba
import operator
import pandas as pd
from wordcloud import WordCloud
from matplotlib import pyplot as plt
相應(yīng)庫(kù)的安裝方法(其實(shí)基本都能通過(guò)pip解決):
# matplotlib中文顯示
plt.rcParams['font.family']=['sans-serif']
plt.rcParams['font.sans-serif']=['SimHei']
不設(shè)置可能出現(xiàn)中文亂碼等鬧心的情況哦~
# 讀取數(shù)據(jù)
key='顯卡'
data=pd.read_csv('%s.csv'%key,encoding='utf-8',engine='python')
# 價(jià)格分布
plt.figure(figsize=(16,9))
plt.hist(data['price'],bins=20,alpha=0.6)
plt.title('價(jià)格頻率分布直方圖')
plt.xlabel('價(jià)格')
plt.ylabel('頻數(shù)')
plt.savefig('價(jià)格分布.png')
價(jià)格頻率分布直方圖:
# 銷售地分布
group_data=list(data.groupby('location'))
loc_num={}
for i in range(len(group_data)):
loc_num[group_data[i][0]]=len(group_data[i][1])
plt.figure(figsize=(19,9))
plt.title('銷售地')
plt.scatter(list(loc_num.keys())[:20],list(loc_num.values())[:20],color='r')
plt.plot(list(loc_num.keys())[:20],list(loc_num.values())[:20])
plt.savefig('銷售地.png')
sorted_loc_num=sorted(loc_num.items(), key=operator.itemgetter(1),reverse=True)#排序
loc_num_10=sorted_loc_num[:10] #取前10
loc_10=[]
num_10=[]
for i in range(10):
loc_10.append(loc_num_10[i][0])
num_10.append(loc_num_10[i][1])
plt.figure(figsize=(16,9))
plt.title('銷售地TOP10')
plt.bar(loc_10,num_10,facecolor='lightskyblue',edgecolor='white')
plt.savefig('銷售地TOP10.png')
銷售地分布:
銷售地TOP10:
# 制作詞云
content=''
for i in range(len(data)):
content +=data['title'][i]
wl=jieba.cut(content,cut_all=True)
wl_space_split=' '.join(wl)
wc=WordCloud('simhei.ttf',
background_color='white', # 背景顏色
width=1000,
height=600,).generate(wl_space_split)
wc.to_file('%s.png'%key)
淘寶商品”顯卡“的詞云:
最后,要說(shuō)點(diǎn)啥呢~
. LYST.COM
https://www.lyst.com/
這個(gè)網(wǎng)站其實(shí)就是一個(gè)網(wǎng)購(gòu)搜索引擎,通過(guò)爬蟲技術(shù),搜羅了全球各大電商購(gòu)物平臺(tái)的各種商品信息。你可以通過(guò)這個(gè)搜索引擎去找想要的潮流單品,不管是什么東西,它都能通過(guò)強(qiáng)大的篩選功能細(xì)致地給你羅列出來(lái),包括顏色、尺碼、款式分類、是否打折等。而且會(huì)對(duì)比各個(gè)平臺(tái),幫你比價(jià),以最實(shí)惠的價(jià)格買到最棒的商品。
所以購(gòu)物前用這個(gè)網(wǎng)站搜一下就對(duì)了,基本上不會(huì)有買貴了的情況。
當(dāng)然有些例外的情況,比如有些品牌的貨品賣不出去,像日韓品牌CDG、三宅一生復(fù)線Homme Plisse、ADER等這些品牌就會(huì)私下給一些渠道商或者代購(gòu)以7-8折的優(yōu)惠去散貨。所以可能有時(shí)候在平臺(tái)上去比價(jià)購(gòu)買,也許還沒(méi)有你在淘寶代購(gòu)那里買的便宜。因?yàn)檫@些品牌在本國(guó)和國(guó)際市場(chǎng)的定價(jià)是不同的,這是由于國(guó)際貿(mào)易中不同國(guó)家的進(jìn)口稅導(dǎo)致的。所以如果想真正的撿到便宜,自己還是平時(shí)要做足功課,了解你喜歡的品牌在本國(guó)和外國(guó)的售價(jià)。
2. MagazineLib
https://magazinelib.com/
非常全的外刊搜索網(wǎng)站,并且提供免費(fèi)的PDF下載。有著強(qiáng)大的篩選功能,分類細(xì)致,每一期都會(huì)羅列出來(lái),基本上你可以挑到所有你喜歡的雜志。
3. 123apps
https://123apps.com/cn/
這是一個(gè)提供在線音樂(lè)剪輯、視頻剪輯、音視頻格式轉(zhuǎn)換、合成音軌等功能。完全免費(fèi),使用方便,精簡(jiǎn)小巧,可直接在瀏覽器上運(yùn)行并完成操作。
我體驗(yàn)了一下里面的視頻剪輯功能,操作很簡(jiǎn)單,視頻導(dǎo)入非常快,導(dǎo)出時(shí)可以選擇畫質(zhì)。還可以裁剪視頻的所需區(qū)域,或更改邊框比例。目前最大支持上傳500M視頻文件。
4. 在線詞云生成工具-微詞云
https://www.weiciyun.com/
這個(gè)網(wǎng)站提供了一款非常簡(jiǎn)單實(shí)用的微詞云生成工具。只需簡(jiǎn)單幾步,選擇合適的背景圖,編輯需要的詞匯,它就能自動(dòng)幫你生成炫酷的詞云,讓人眼前一亮。
除此之外,它還有強(qiáng)大的設(shè)計(jì)功能,每個(gè)字的字體、顏色、大小、分布等都可以進(jìn)行設(shè)置。這比使用PS設(shè)計(jì)詞云Logo封面簡(jiǎn)單太多。
5. 米范-酷導(dǎo)航
https://www.mifar.net/
這是一個(gè)專門為新媒體和電商從業(yè)者設(shè)計(jì)的導(dǎo)航網(wǎng)站,目前導(dǎo)航共有 運(yùn)營(yíng)營(yíng)銷、電子商務(wù)、數(shù)據(jù)信息、圖像影音、前端設(shè)計(jì)、網(wǎng)站建設(shè)和實(shí)用工具七個(gè)大分類,收錄了100+新媒體人必備工具,公眾號(hào)排版、無(wú)版權(quán)圖庫(kù)、裂變?cè)鲩L(zhǎng)、社群運(yùn)營(yíng)、數(shù)據(jù)分析、創(chuàng)意H5、流量采買等等。
如果你被排版編輯、編輯制作、數(shù)據(jù)收集和網(wǎng)站建設(shè)所困擾,翻翻米范或許可以獲得一絲靈感。
6. 秘搭寫作貓
https://xiezuocat.com/
秘塔寫作貓是一個(gè)不可多得的 AI 智能寫作工具,它專注于中文寫作,功能非常強(qiáng)大,每個(gè)功能都可以幫助你更好的進(jìn)行中文寫作。
首先,它支持實(shí)時(shí)錯(cuò)誤提示,你可以直接在網(wǎng)站里面進(jìn)行寫作,網(wǎng)站會(huì)實(shí)時(shí)提示你的錯(cuò)誤,包括:字詞錯(cuò)誤、標(biāo)點(diǎn)誤用、語(yǔ)序錯(cuò)誤、語(yǔ)法問(wèn)題、同義混淆,并且給出具體的修改建議。
它的高級(jí)提示功能還包括:專有名詞大小寫檢查、詞語(yǔ)一致性檢查、成語(yǔ)搭配、量詞搭配、形近字、語(yǔ)法分析、情感分析、語(yǔ)序分析等。
它支持全文改寫功能,這個(gè)功能可以幫助你一鍵修改文章的錯(cuò)誤,讓你的文章瞬間變得高級(jí)自然,并且用下劃線展示了具體修改的地方。
最后,網(wǎng)站并不是完全免費(fèi)的,提供免費(fèi)版、基礎(chǔ)版、高級(jí)版,免費(fèi)版的功能和高級(jí)版其實(shí)差不多,免費(fèi)版也足夠滿足日常使用需求,但是越高版本的單日處理字?jǐn)?shù)、單篇處理字?jǐn)?shù)、翻譯字?jǐn)?shù)也會(huì)越高。
7. 熊貓搜書
https://ebook.huzerui.com/
熊貓搜書是一個(gè)非常好用的電子書導(dǎo)航網(wǎng)站,一個(gè)網(wǎng)站相當(dāng)于很多個(gè)網(wǎng)站。
它聚合了多達(dá) 20 多個(gè)高質(zhì)量電子書網(wǎng)站,并且每個(gè)網(wǎng)站的質(zhì)量都是非常高,它的界面簡(jiǎn)潔清新,你可以直接點(diǎn)擊左側(cè)切換網(wǎng)站。
8. PPT超級(jí)市場(chǎng)
http://ppt.sotary.com/web/wxapp/index.html
PPT 超級(jí)市場(chǎng)是一個(gè)完全免費(fèi)的 PPT 模板下載網(wǎng)站。里面每一個(gè) PPT 模板的質(zhì)量都是極高,并且非常精美。
它的界面非常簡(jiǎn)潔,沒(méi)有任何多余的東西,只有一個(gè)簡(jiǎn)單的搜索框和部分推薦模板,你可以直接利用網(wǎng)站的搜索功能搜索你需要的 PPT 模板。
搜索完畢,你就可以點(diǎn)擊下載按鈕直接下載 PPT 模板。
9.全歷史
https://www.allhistory.com/
這個(gè)網(wǎng)站把每個(gè)國(guó)家的歷史用時(shí)間軸的形式串了起來(lái)。點(diǎn)擊一下朝代,就可以看到這個(gè)朝代的大事件和代表人物。
除此之外,里面的AI關(guān)系圖譜功能提供了世界上各種人物、歷史、文化、商業(yè)、科學(xué)等關(guān)系樹狀圖。
時(shí)間地圖功能還可以讓你選擇穿越回任意時(shí)代的疆域版圖,根據(jù)不同年份詳細(xì)標(biāo)注了不一樣的人物和事件。
F L O T ?
END
最后一個(gè),忘記說(shuō)了
封面的Pornhub體LOGO生成網(wǎng)站
由V2EX論壇KasuganoSoras制作
Pornhub
https://www.zerobbs.net/pornhub/
YouTube
https://www.zerobbs.net/youtube/
如對(duì)本稿件有異議或投訴,請(qǐng)聯(lián)系flot_official@163.com
用Selenium來(lái)模擬瀏覽器操作,抓取淘寶商品信息,并將結(jié)果保存到MongoDB。
1.準(zhǔn)備工作
本文以Chrome為例來(lái)講解Selenium的用法。在開始之前,請(qǐng)確保已經(jīng)正確安裝好了Chrome瀏覽器并配置好了ChromeDriver;另外,還需要正確安裝Python的Selenium庫(kù)。
2.接口分析
首先,我們來(lái)打開淘寶的接口,觀察一下它的ajax請(qǐng)求。
打開淘寶頁(yè)面,搜索商品,比如ipad,此時(shí)打開開發(fā)者工具,查看Ajax請(qǐng)求,我們可以發(fā)現(xiàn),根本沒(méi)有Ajax請(qǐng)求,如圖
不過(guò)沒(méi)有關(guān)系,我們可以直接用Selenium來(lái)模擬瀏覽器,只要在瀏覽器里能看到的,都可以爬取。這也是我們選擇使用Selenium的原因。
3.頁(yè)面分析
我們的目標(biāo)是爬取商品信息。如圖是一個(gè)商品條目,其中包含商品的基本信息,包括商品圖片、名稱、價(jià)格、購(gòu)買人數(shù)、店鋪名稱和店鋪所在地,我們要做的就是將這些信息都抓取下來(lái)。
抓取入口就是淘寶的搜索頁(yè)面,這個(gè)鏈接可以通過(guò)直接構(gòu)造參數(shù)訪問(wèn)。例如,如果搜ipad,就可以直接訪問(wèn)https://s.taobao.com/search?q=ipad,呈現(xiàn)的就是第一頁(yè)的搜索結(jié)果,如圖所示
在頁(yè)面下方,有一個(gè)分頁(yè)導(dǎo)航,其中既包括前5頁(yè)的鏈接,也包括下一個(gè)的鏈接,同時(shí)還有一個(gè)輸入任意頁(yè)碼跳轉(zhuǎn)的鏈接,如圖
這里商品搜索的結(jié)果一般最大都是100頁(yè),要獲取每一頁(yè)的內(nèi)容,只需要將頁(yè)碼從1到100順序遍歷即可,頁(yè)碼數(shù)是確定的。所以,直接在頁(yè)面跳轉(zhuǎn)文本框中輸入要跳轉(zhuǎn)的頁(yè)碼,然后點(diǎn)擊“確定”按鈕即可跳轉(zhuǎn)到頁(yè)碼對(duì)應(yīng)的頁(yè)面。
這里不直接點(diǎn)擊“下一頁(yè)”的原因是:一旦爬取過(guò)程中出現(xiàn)異常退出,比如到50頁(yè)退出了,此時(shí)點(diǎn)擊“下一頁(yè)”時(shí),就無(wú)法快速切換到對(duì)應(yīng)的后續(xù)頁(yè)面了。此外,在爬取過(guò)程中,也需要記錄當(dāng)前的頁(yè)碼數(shù),而且點(diǎn)擊“下一頁(yè)”之后頁(yè)面加載失敗,還需要做異常檢測(cè),檢測(cè)當(dāng)前頁(yè)面是加載到了第幾頁(yè)。整個(gè)流程比較復(fù)雜,所以我們這里直接用跳轉(zhuǎn)的方式來(lái)爬取頁(yè)面。
當(dāng)我們成功的加載出某一頁(yè)商品列表時(shí),利用Selenium即可獲取頁(yè)面源代碼,然后再用相應(yīng)的解析庫(kù)解析即可。這里我們選用pyquery解析。下面我們用代碼實(shí)現(xiàn)整個(gè)抓取過(guò)程。
4.獲取商品列表
首先,需要構(gòu)造一個(gè)抓取的URL:https://s.taobao.com/search?q=ipad。這個(gè)URL非常簡(jiǎn)潔,參數(shù)q就是要搜索的關(guān)鍵字。只要改變這個(gè)參數(shù),即可獲取不同的商品列表。這里我們將商品的關(guān)鍵字定義成一個(gè)變量,然后構(gòu)造出這樣的一個(gè)URL。
然后就需要用Selenium進(jìn)行抓取了。我們實(shí)現(xiàn)了如下抓取列表頁(yè)的方法:
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
import time
browser=webdriver.Chrome()
wait=WebDriverWait(browser,10)
KEYWORD='ipad'
def index_page(page):
"""
抓取索引頁(yè)
:param page: 頁(yè)碼
"""
print('正在爬取第',page,'頁(yè)')
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)
這里首先構(gòu)造了一個(gè)WebDriver對(duì)象,使用的瀏覽器是Chrome,然后指定一個(gè)關(guān)鍵詞,如ipad,接著定義了index_age()方法,用于抓取商品列表頁(yè)。
在該方法里,我們首先訪問(wèn)了搜索商品的鏈接,然后判斷了當(dāng)前的頁(yè)碼,如果大于1,就進(jìn)行跳頁(yè)操作,否則等待頁(yè)面加載完成。
等待加載時(shí),我們使用了WebDriverWait對(duì)象,它可以指定等待條件,同時(shí)指定一個(gè)最長(zhǎng)等待時(shí)間,這里指定為10s。如果在這個(gè)時(shí)間內(nèi)成功匹配了等待條件,也就是說(shuō)頁(yè)面元素成功加載出來(lái)了,就立即返回相應(yīng)結(jié)果并繼續(xù)向下執(zhí)行,否則到了最大等待時(shí)間還沒(méi)有加載出來(lái)時(shí),就直接拋出超時(shí)異常。
比如,我們最終要等待商品信息加載出來(lái),就指定了presnece_of_element_located這個(gè)條件,然后傳入了.m-itemlist .items .item這個(gè)選擇器,而這個(gè)選擇器對(duì)應(yīng)的頁(yè)面內(nèi)容就是每個(gè)商品的信息塊,可以在網(wǎng)頁(yè)中查看。如果加載成功,就會(huì)執(zhí)行后續(xù)的get_products()方法,提取商品信息。
關(guān)于翻頁(yè)操作,這里首先獲取頁(yè)碼輸入框,賦值為input,然后獲取“確定”按鈕,賦值為submit,分別是圖中的兩個(gè)元素。
首先,我們清空了輸入框,此時(shí)調(diào)用clear()方法即可。隨后,調(diào)用send_keys()方法將頁(yè)碼填充到輸入框中,然后點(diǎn)擊“確定按鈕即可”
那么,怎么樣知道有沒(méi)有跳轉(zhuǎn)到對(duì)應(yīng)的頁(yè)碼呢?我們可以注意到,成功跳轉(zhuǎn)到某一頁(yè)后,頁(yè)碼都會(huì)高亮顯示,如圖
我們只需要判斷當(dāng)前高亮的頁(yè)碼數(shù)是當(dāng)前的頁(yè)碼數(shù)即可,所以這里使用了另一個(gè)等待條件text_to_be_present_in_element,它會(huì)等待指定的文本出現(xiàn)在某一個(gè)節(jié)點(diǎn)里面時(shí)即返回成功。這里我們將高亮的頁(yè)碼節(jié)點(diǎn)對(duì)應(yīng)的CSS選擇器和當(dāng)前要跳轉(zhuǎn)的頁(yè)碼通過(guò)參數(shù)傳遞給這個(gè)等待條件,這樣它就會(huì)檢測(cè)當(dāng)前高亮的頁(yè)碼節(jié)點(diǎn)是不是我們傳過(guò)來(lái)的頁(yè)碼數(shù),如果是,就證明頁(yè)面成功跳轉(zhuǎn)到了這一頁(yè),頁(yè)面跳轉(zhuǎn)成功。
這樣剛才實(shí)現(xiàn)的index_page()方法就可以傳入對(duì)應(yīng)的頁(yè)碼,待加載出對(duì)應(yīng)頁(yè)碼的商品列表后,再去調(diào)用get_products()方法進(jìn)行頁(yè)面解析。
5.解析商品列表
接下來(lái),我們就可以實(shí)現(xiàn)get_products()方法來(lái)解析商品列表了。這里我們直接獲取頁(yè)面源代碼,然后用pyquery進(jìn)行解析,實(shí)現(xiàn)如下:
from pyquery import PyQuery as pq
def get_products():
"""
提取商品數(shù)據(jù)
"""
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)
首先,調(diào)用page_source屬性獲取頁(yè)碼的源代碼,然后構(gòu)造了PyQuery對(duì)象,提取了商品列表,此時(shí)使用的CSS選擇器是#mainsrp-itemlist .items .item,它會(huì)匹配整個(gè)頁(yè)面的每個(gè)商品。它的匹配結(jié)果是多個(gè),所以這里我們又對(duì)它進(jìn)行了一次遍歷,用for循環(huán)將每個(gè)結(jié)果分別進(jìn)行解析,每次循環(huán)把它賦值為item變量,每個(gè)item變量都是一個(gè)PyQuery對(duì)象,然后再調(diào)用它的find()方法,傳入CSS選擇器,就可以獲取單個(gè)商品的特定內(nèi)容。
比如查看一下商品源碼
可以發(fā)現(xiàn),它是一個(gè)img節(jié)點(diǎn),包含id、class、data-src、alt和src屬性,這里之所以可以看到這樣圖片,是因?yàn)樗膕rc屬性被賦值為圖片的URL。把它的src屬性提取出來(lái),就可以獲取商品的完整圖片了。不過(guò)我們還注意data-src屬性,它的圖片內(nèi)容也是圖片的URL,觀察后發(fā)現(xiàn)此URL是圖片的完整大圖,而src是壓縮后的小圖,所以這里抓取data-src屬性來(lái)作為商品的圖片。
因此,我們需要先利用find()方法找到圖片的這個(gè)節(jié)點(diǎn),然后再調(diào)用attr()方法獲取商品的data-src屬性,這樣就成功提取了商品的鏈接。然后用同樣的方法提取商品的價(jià)格、成交量、名稱、店鋪所在地等信息,接著將所有提取結(jié)果賦值為一個(gè)字典product,然后調(diào)用save_mongo()將其保存到MongoDB即可。
6.保存到MongoDB
接下來(lái),我們將商品信息保存到MongoDB,代碼如下:
import pymongo
MONGO_URL='localhost'
MONGO_DB='taobao'
MONGO_COLLECTION='products'
client=pymongo.MongoClient(MONGO_URL)
db=client[MONGO_DB]
def save_to_mongo(result):
"""
保存結(jié)果到MongoDB
"""
try:
if db[MONGO_COLLECTION].insert(result):
print('存儲(chǔ)到MongoDB成功')
except Exception:
print('存儲(chǔ)到MongoDB失敗')
這里首先創(chuàng)建了一個(gè)MongoDB的連接對(duì)象,然后指定了數(shù)據(jù)庫(kù),隨后指定了Collection的名稱,接著調(diào)用insert()方法將數(shù)據(jù)庫(kù)插入到MongoDB。此處的result的變量就是在get_products()方法里傳來(lái)的product,包含單個(gè)商品的信息。
7.遍歷每頁(yè)
剛才我們所定義的get_index()方法需要接收參數(shù)page,page代碼頁(yè)碼。這里我們實(shí)現(xiàn)頁(yè)碼遍歷即可,代碼如下:
MAX_PAGE=10
def main():
"""
遍歷
:return:
"""
for i in range(1,MAX_PAGE+1):
index_page(i)
time.sleep(10)
main()
最后調(diào)用main()方法即可運(yùn)行。
8.異常處理(繞過(guò)登錄反爬機(jī)制)
當(dāng)寫到這里,如果運(yùn)行程序會(huì)發(fā)現(xiàn),程序在彈出瀏覽器窗口后,會(huì)出現(xiàn)登陸頁(yè)面,但是當(dāng)你嘗試輸入賬戶密碼時(shí),滑塊的驗(yàn)證始終失效。并且頁(yè)面還會(huì)不斷刷新。如圖
針對(duì)這種情況,博主找到了兩種解決方案
方法一:修改ChromeDriver.exe
之所以出現(xiàn)這種情況,是因?yàn)樵谔詫毜牡卿涰?yè)面,有這樣一個(gè)js,它會(huì)判斷你是通過(guò)驅(qū)動(dòng)打開的瀏覽器還是其他情況,如果是驅(qū)動(dòng)打開那么這個(gè)判斷為真就會(huì)出現(xiàn)這種情況,如圖,為判斷的js
我們?cè)诳刂婆_(tái)運(yùn)行一下這個(gè)腳本window.navigator.webdriver
可以看到,判斷為真,說(shuō)明瀏覽器知道我們使用的是驅(qū)動(dòng)。
那該如何解決呢?
首先,使用nodepad++或者記事本打開chrome,查找$cdc,找到這串代碼后,將其用等長(zhǎng)的字符串替代即可,例如把最后的l改成a。
然后把部分代碼改為如下模式,將瀏覽器設(shè)置為開發(fā)者模式:
option=webdriver.ChromeOptions()
#開發(fā)者模式的開關(guān),設(shè)置一下,打開瀏覽器就不會(huì)識(shí)別為自動(dòng)化測(cè)試工具了
option.add_experimental_option('excludeSwitches', ['enable-automation'])
driver=webdriver.Chrome(chrome_options=option)
如果這種方法不能奏效,請(qǐng)看第二種方法
方法二:將用戶信息的配置文件在代碼中加載
首先,在Chrome中輸入chrome://version/查看信息。如圖,這是我們用戶信息。
然后在代碼中,加載瀏覽器配置
chrome_option=webdriver.ChromeOptions()
p=r'C:\Users\趙磊\AppData\Local\Google\Chrome\User Data'
#chrome_option.add_experimental_option('excludeSwitches', ['enable-automation']) # 以開發(fā)者模式
chrome_option.add_argument('--user-data-dir='+p)
browser=webdriver.Chrome(options=chrome_option)
wait=WebDriverWait(browser,10)
這樣在爬取時(shí)就不會(huì)出現(xiàn)登錄頁(yè)面了。
9.運(yùn)行
此時(shí)運(yùn)行代碼,會(huì)發(fā)現(xiàn)彈出一個(gè)Chrome瀏覽器,然后會(huì)訪問(wèn)淘寶頁(yè)面,接著控制臺(tái)輸出如下
可以發(fā)現(xiàn),這些商品信息的結(jié)果都是字典形式,它們倍存儲(chǔ)到MongoDB里面,再看一下MongoDB中的結(jié)果
說(shuō)明信息保存到MongoDB中,爬取成功。
selenium有多種編程語(yǔ)言的客戶端驅(qū)動(dòng),編寫自動(dòng)化腳本語(yǔ)法簡(jiǎn)潔,其中python的selenium庫(kù)便非常的受歡迎。
你可以使用selenium做web測(cè)試或者爬蟲,自動(dòng)搶票、自動(dòng)下單也可以用selenium來(lái)做。
演示自動(dòng)打開淘寶網(wǎng):
# 導(dǎo)入庫(kù)
from selenium import webdriver
import datetime
import time
# 記錄時(shí)間
now=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')
# 打開chrome
browser=webdriver.Chrome()
# 登錄
def login():
# 打開淘寶首頁(yè),通過(guò)掃碼登錄
browser.get("https://www.taobao.com/")
time.sleep(3)
# 打開登錄界面
find_login=browser.find_element_by_link_text("親,請(qǐng)登錄")
if find_login:
find_login.click()
print("請(qǐng)掃碼登錄")
time.sleep(10)
login()
# 選擇購(gòu)物車列表
def picking(method):
# 是否全選購(gòu)物車
if method==0:
while True:
try:
if browser.find_element_by_id("J_SelectAll1"):
browser.find_element_by_id("J_SelectAll1").click()
print('全選購(gòu)物車成功')
break
except:
print(f"找不到購(gòu)買按鈕")
else:
print(f"請(qǐng)手動(dòng)勾選需要購(gòu)買的商品")
time.sleep(1)
# 點(diǎn)擊結(jié)算按鈕
def settlement():
while True:
try:
if browser.find_element_by_id('J_SelectedItemsCount').text >='1':
browser.find_element_by_link_text("結(jié) 算").click()
print(f"結(jié)算成功,準(zhǔn)備提交訂單")
break
except:
pass
# 點(diǎn)擊提交訂單按鈕
def submitting():
while True:
try:
if browser.find_element_by_link_text('提交訂單'):
browser.find_element_by_link_text('提交訂單').click()
print(f"搶購(gòu)成功,請(qǐng)盡快付款")
break
except:
print(f"再次嘗試提交訂單")
def run(times):
# 打開購(gòu)物車列表頁(yè)面
print('正在搶購(gòu)!')
browser.get("https://cart.taobao.com/cart.htm")
time.sleep(3)
while True:
now=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')
# 對(duì)比時(shí)間,時(shí)間到的話就點(diǎn)擊結(jié)算
if now > times:
# 全選購(gòu)物車
picking(0)
# 點(diǎn)擊結(jié)算按鈕
settlement()
# 提交訂單
submitting()
print(now)
break
希望本文對(duì)你有所幫助~~如果對(duì)軟件測(cè)試、接口測(cè)試、自動(dòng)化測(cè)試、性能測(cè)試、面試經(jīng)驗(yàn)交流感興趣可以私聊我或關(guān)注公眾號(hào)“特斯汀軟件測(cè)試”。免費(fèi)領(lǐng)取最新軟件測(cè)試大廠面試資料和Python自動(dòng)化、接口、框架搭建學(xué)習(xí)資料!技術(shù)大牛解惑答疑,同行一起交流。
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。