版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
網(wǎng)絡(luò)爬蟲項(xiàng)目實(shí)戰(zhàn)項(xiàng)目一:網(wǎng)頁數(shù)據(jù)獲取主講人:xxx全套可編輯PPT課件項(xiàng)目1:網(wǎng)頁數(shù)據(jù)獲取項(xiàng)目2:特殊網(wǎng)頁數(shù)據(jù)獲取項(xiàng)目3:scrapy框架爬蟲項(xiàng)目4:分布式爬蟲231任務(wù)1.2今日頭條數(shù)據(jù)爬取
任務(wù)1.1讀書網(wǎng)信息爬取任務(wù)1.3京東動(dòng)態(tài)渲染頁面的信息爬取目錄任務(wù)1.1讀書網(wǎng)信息爬取任務(wù)描述讀書網(wǎng)是中國(guó)國(guó)內(nèi)優(yōu)秀的讀書平臺(tái),同時(shí)也是集書籍查詢、作者介紹、刊物定價(jià)、出版社、ISBN查詢的公益讀書網(wǎng)站。在網(wǎng)站首頁有一個(gè)“在線讀書”欄目,本任務(wù)的目的是爬取“在線讀書”欄目中圖書的詳情頁鏈接、書名和作者信息,“在線讀書”欄目如圖所示。任務(wù)目標(biāo)要實(shí)現(xiàn)讀書網(wǎng)“在線讀書”欄目中圖書的詳情頁鏈接、書名和作者信息,需要學(xué)習(xí)以下知識(shí):掌握使用正則表達(dá)式爬取數(shù)據(jù)的方法掌握處理爬取數(shù)據(jù)亂碼的方法掌握爬取連接不完整情況處理的方法1.網(wǎng)頁結(jié)構(gòu)分析進(jìn)入讀書網(wǎng)網(wǎng)站首頁,按F12鍵查看網(wǎng)頁源代碼,如圖1-2所示。從源代碼可以看出,整個(gè)在線讀書是用一個(gè)div標(biāo)簽標(biāo)包括起來的,每一本書用一個(gè)li標(biāo)簽表示,本任務(wù)需要爬取的書籍鏈接由a標(biāo)簽的href屬性標(biāo)示,書名由a標(biāo)簽包括起來,作者信息由標(biāo)有class=“bookauthor”的div標(biāo)簽包括。通過源碼分析,會(huì)發(fā)現(xiàn)一個(gè)問題,網(wǎng)頁源碼中的書籍鏈接信息只有一部分,而不是完整鏈接,因此需要進(jìn)行URL補(bǔ)全。任務(wù)實(shí)施2.解決爬蟲中文亂碼通過F12鍵查看網(wǎng)頁源代碼的head部分的編碼,如圖1-8所示,發(fā)現(xiàn)網(wǎng)頁編碼類型為UTF-8。任務(wù)實(shí)施利用requests庫的encoding方法查看默認(rèn)輸出的編碼類型,代碼如下:importrequestsresponse=requests.get('/')print(response.encoding)2.解決爬蟲中文亂碼利用requests庫encoding方法改變輸出結(jié)果的編碼,代碼如下:任務(wù)實(shí)施importrequestsresponse=requests.get('/')response.encoding='utf-8'print(response.encoding)3.網(wǎng)頁數(shù)據(jù)爬取代碼編寫時(shí)將網(wǎng)頁源碼獲取,編碼方式設(shè)置等封裝為一個(gè)方法,代碼如下:任務(wù)實(shí)施defget_html(url):try:response=requests.get(url)response.encoding='utf-8'#改變編碼
print(response.encoding)html=response.textreturnhtmlexcept:print('請(qǐng)求網(wǎng)址出錯(cuò)')content=get_html('/')3.網(wǎng)頁數(shù)據(jù)爬取通過源碼分析,可以看出每一本書用一個(gè)li標(biāo)簽表示,本任務(wù)需要爬取的書籍鏈接由a標(biāo)簽的href屬性標(biāo)示,書名由a標(biāo)簽包括起來,作者信息由標(biāo)有class=“bookauthor”的div標(biāo)簽包括。而為了進(jìn)行一定的限定,已做到精確匹配,可以在正則表達(dá)式中加上“class="bookname"”、“target="_blank"”和“class="bookauthor"”等關(guān)鍵信息的限定。因此根據(jù)源碼,寫出正則表達(dá)式如下:任務(wù)實(shí)施<li>.*?class="bookname">.*?href="(.*?)".*?target="_blank">(.*?)</a>.*?class="bookauthor">(.*?)</div>.*?</li>3.網(wǎng)頁數(shù)據(jù)爬取將正則字符轉(zhuǎn)換為正則表達(dá)式需要用到re庫中的compile方法。pile:將正則字符串編譯成正則表達(dá)式對(duì)象,以便于復(fù)用該匹配模式。pile一般需要傳入兩個(gè)參數(shù):①第一個(gè)參數(shù):正則字符。②第二個(gè)參數(shù):匹配模式。匹配模式:正則表達(dá)式可以包含一些可選標(biāo)志修飾符來控制匹配模式。常見的修飾符有6中,具體含義如表所示。任務(wù)實(shí)施修飾符描述re.I使匹配對(duì)大小寫不敏感re.L做本地化識(shí)別(locale-aware)匹配re.M多行匹配,影響^和$re.S使*匹配包括換行在內(nèi)的所有字符re.U根據(jù)Unicode字符集解析字符。這個(gè)標(biāo)志影響\w、\W、\b和\Bre.X該標(biāo)志通過給予你更靈活的格式以便你將正則表達(dá)式寫的更易于理解3.網(wǎng)頁數(shù)據(jù)爬取用于查找匹配內(nèi)容的方法采用re庫中的findall方法。findall:搜索字符串,以列表形式返回全部能匹配的子串。一般需要傳入兩個(gè)參數(shù):第一個(gè)參數(shù):正則表達(dá)式。第二個(gè)參數(shù):匹配的內(nèi)容。返回結(jié)果:列表。因此輸入打印返回結(jié)果的需要循環(huán)輸出。任務(wù)實(shí)施3.網(wǎng)頁數(shù)據(jù)爬取通過查看源碼,發(fā)現(xiàn)源碼中a標(biāo)簽屬性href中確實(shí)只有部分URL,但是將鼠標(biāo)移至href鏈接時(shí)會(huì)彈出完整鏈接,完整鏈接如圖所示。對(duì)比爬取結(jié)果,發(fā)現(xiàn)爬取結(jié)果缺少“”段網(wǎng)站,因此在打印時(shí)應(yīng)該補(bǔ)全。任務(wù)實(shí)施完整代碼任務(wù)實(shí)施#讀書網(wǎng)爬蟲任務(wù)importrequestsimportredefget_html(url):
try:
response=requests.get(url)
response.encoding='utf-8'
#改變編碼
print(response.encoding)
html=response.text
returnhtml
except:
print('請(qǐng)求網(wǎng)址出錯(cuò)')content=get_html('/')pattern=pile('<li>.*?class="bookname">.*?href="(.*?)".*?target="_blank">(.*?)</a>.*?class="bookauthor">(.*?)</div>.*?</li>',re.S)results=re.findall(pattern,content)forresultinresults:
url,name,author=result
print(""+url,name,author)請(qǐng)將書海網(wǎng)圖書鏈接和書名信息爬取下來課后習(xí)題任務(wù)1.2今日頭條數(shù)據(jù)爬取任務(wù)描述瀏覽網(wǎng)頁的時(shí)候,經(jīng)常會(huì)發(fā)現(xiàn)很多網(wǎng)頁都有下滑查看更多的選項(xiàng)。如圖所示的今日頭條(/)網(wǎng)站,剛剛進(jìn)入后只會(huì)展現(xiàn)有限的新聞,但是隨著網(wǎng)頁的不斷下滑,可以瀏覽更多的新聞。如果遇到這樣的頁面,直接利用requests等庫來抓取原始頁面,是無法獲取到有效數(shù)據(jù)的,這時(shí)需要分析網(wǎng)頁后臺(tái)向接口發(fā)送的AJAX請(qǐng)求,如果可以用requests來模擬AJAX請(qǐng)求,那么就可以成功抓取了。在今日頭條中搜索關(guān)鍵字過濾重定向網(wǎng)頁下載圖片信息保存至本地保存鏈接信息至mongoDB任務(wù)目標(biāo)今日頭條是采用AJAX持續(xù)不斷的請(qǐng)求內(nèi)容,因此在抓取網(wǎng)頁數(shù)據(jù)時(shí)候,需要發(fā)送AJAX請(qǐng)求,而不是普通請(qǐng)求。進(jìn)入今日頭條官網(wǎng)(/),在搜索框中輸入“街拍”,可以進(jìn)入搜索結(jié)果頁面。此時(shí)按F12鍵調(diào)出開發(fā)人員工具,然后刷新頁面。在開發(fā)人員工具中,點(diǎn)擊Network,勾選“Preservelog”和“HidedataURLs”,并點(diǎn)擊All,會(huì)發(fā)現(xiàn)此時(shí)的Preview中的內(nèi)容被隱藏了。如圖1-14所示預(yù)覽內(nèi)容被隱藏,也就是返回?cái)?shù)據(jù)被隱藏起來了。任務(wù)實(shí)施1爬取網(wǎng)頁數(shù)據(jù)切換到“XHR”選項(xiàng),這時(shí)在Preview選項(xiàng)中就可以找到返回來的Json數(shù)據(jù),如圖1-15所示,頁面中的數(shù)據(jù)被以Json返回,并且在Json數(shù)據(jù)中的key為“data”。任務(wù)實(shí)施1爬取網(wǎng)頁數(shù)據(jù)切換到“Headers”選項(xiàng)卡,這是可以看到“RequestURL”中寫的URL是以“/api/search/content/?”開頭的地址,而實(shí)際瀏覽器中的地址是“/search/?keyword=街拍”,可以看出今日頭條網(wǎng)站對(duì)將實(shí)際請(qǐng)求數(shù)據(jù)的網(wǎng)站進(jìn)行了變換,所以我們爬蟲的時(shí)候需要用“RequestURL”中的地址,如圖1-16所示。任務(wù)實(shí)施1爬取網(wǎng)頁數(shù)據(jù)兩個(gè)參數(shù)需要特別注意,一個(gè)是“offset”,這個(gè)參數(shù)代表網(wǎng)頁每次發(fā)送Ajax請(qǐng)求是的偏移量,另外一個(gè)是“count”,這個(gè)參數(shù)代表每次請(qǐng)求返回多少條數(shù)據(jù)。如圖1-18所示,每次請(qǐng)求的offset是遞增,offset開始時(shí)為0,count為20,所以第二次請(qǐng)求的時(shí)候offset的值就為20了,以此類推。任務(wù)實(shí)施1爬取網(wǎng)頁數(shù)據(jù)在Python代碼實(shí)現(xiàn)過程中,可以定義一個(gè)字典表示圖1-16中的參數(shù),具體代碼如下:任務(wù)實(shí)施1爬取網(wǎng)頁數(shù)據(jù)params={'aid':24,'app_name':'web_search','offset':offset,'format':'json','keyword':keyword,'autoload':'true','count':'20','en_qc':1,'cur_tab':'1','from':'search_tab','pd':'synthesis','timestamp':1578048043413}使用urllib庫里urlencode函數(shù),urlencode函數(shù)可以把key-value這樣的鍵值對(duì)轉(zhuǎn)換成我們想要的格式,返回的是a=1&b=2這樣的字符串。如下列代碼的運(yùn)行結(jié)果為“http:/?a=1&b=2”:任務(wù)實(shí)施1爬取網(wǎng)頁數(shù)據(jù)fromurllib.parseimporturlencodedata={"a":1,"b":2}url="http:/?"print(url+urlencode(data))將獲取網(wǎng)頁的代碼封裝成get_page_index方法運(yùn)行上述代碼,會(huì)發(fā)現(xiàn)結(jié)果為空,返回的json數(shù)據(jù)為空的原因是requests的請(qǐng)求對(duì)象沒有加請(qǐng)求頭和cookies,因此加上請(qǐng)求頭和cookies并進(jìn)行相應(yīng)的異常處理。任務(wù)實(shí)施1爬取網(wǎng)頁數(shù)據(jù)在今日頭條網(wǎng)站上,搜索“街拍”,返回的是一條一條的搜索結(jié)果,如果想要查看每一條結(jié)果的詳情,需要點(diǎn)擊每一條結(jié)果,在爬蟲里面是需要從新發(fā)送一條請(qǐng)求,這時(shí)我們需要知道,該結(jié)果的URL地址。要獲得搜索結(jié)果詳情,第一步則需要獲得結(jié)果詳情頁的URL。獲取到搜索結(jié)果的URL后,就可以利用URL獲得搜索結(jié)果詳情頁中的數(shù)據(jù)了。任務(wù)實(shí)施2獲取搜索結(jié)果詳情圖
每一條結(jié)果的詳細(xì)JSON數(shù)據(jù)定義方法get_page_url用于獲取詳情頁訪問鏈接,具體代碼如下:任務(wù)實(shí)施2獲取搜索結(jié)果詳情圖
每一條結(jié)果的詳細(xì)JSON數(shù)據(jù)defget_page_url(html):data=json.loads(html)#將json字符串轉(zhuǎn)換為json變量
ifdataand"data"indata.keys():foritemindata.get("data"):#知識(shí)點(diǎn)3:字典獲取鍵的值的get方法
if"article_url"initem.keys():url=item.get("article_url")yieldurl獲取到搜索結(jié)果的URL后,就可以利用URL獲得搜索結(jié)果詳情頁中的數(shù)據(jù)了,具體代碼如下:任務(wù)實(shí)施2獲取搜索結(jié)果詳情圖
每一條結(jié)果的詳細(xì)JSON數(shù)據(jù)defget_page_detial(url):try:#知識(shí)點(diǎn)4:請(qǐng)求的異常處理方式
response=requests.get(url,headers=headers,cookies=cookies)ifresponse.status_code==200:content=response.content.decode()returncontentreturnNoneexceptRequestException:print("請(qǐng)求出錯(cuò)")returnNone在上一步已經(jīng)獲取到了詳情頁的數(shù)據(jù),接下來將講述如何獲取詳情頁中的“title”、圖片和視頻數(shù)據(jù)。1、獲取“title”信息2、獲取并下載圖片3、獲取并下載視頻新建一個(gè)方法,命名為“parse_page_detial”具體代碼如下:任務(wù)實(shí)施3解析詳情頁數(shù)據(jù)defparse_page_detial(content,url):"""正則獲取gallery"""soup=BeautifulSoup(content,"lxml")1、獲取“title”信息按F12鍵,選擇Network,點(diǎn)擊Doc,然后選擇Response,在Response可以看到網(wǎng)頁的源代碼,這里的源碼都是顯示成一行,不方便查看,可以將源碼復(fù)制到其他軟件格式化后查看。如圖1-21所示詳情頁源碼,可以看到任務(wù)要獲取的“title”信息在源碼中用<title>標(biāo)簽包括住任務(wù)實(shí)施3解析詳情頁數(shù)據(jù)1、獲取“title”信息這里采用BeautifulSoup的find方法獲取標(biāo)簽中的信息,在“parse_page_detial”方法中添加如下代碼任務(wù)實(shí)施3解析詳情頁數(shù)據(jù)if(soup.find("title")!=None):title=soup.find("title").string#知識(shí)點(diǎn)5:soup的選擇器使用2、獲取并下載圖片使用相同的方式查看源碼,如圖1-22所示,和title不同的是,圖片的鏈接都在<img>標(biāo)簽的src屬性中。這里采用正則表達(dá)式獲取圖片鏈接,在“parse_page_detial”方法中添加如下代碼:任務(wù)實(shí)施3解析詳情頁數(shù)據(jù)images_pattern=pile('<img.*?src="(.*?)".*?>',re.S)#知識(shí)點(diǎn)6:正則模式re.S模式images=re.findall(images_pattern,content)2、獲取并下載圖片由于網(wǎng)頁詳情頁中可能不止一張圖片,所以需要通過for循環(huán)得到所有圖片鏈接,并進(jìn)行下載。在“parse_page_detial”方法中添加如下代碼:任務(wù)實(shí)施3解析詳情頁數(shù)據(jù)forimageinimages:download_image(image)其中“download_image”方法用于下載圖片,具體代碼如下:任務(wù)實(shí)施3解析詳情頁數(shù)據(jù)defdownload_image(url):print('正在下載圖片',url)try:response=requests.get(url,headers=my_header)ifresponse.status_code==200:#圖片要以二進(jìn)制的形式保存
save_image(response.content)returnNoneexceptRequestException:print('請(qǐng)求圖片出錯(cuò)',url)returnNone新建一個(gè)方法保存圖片,命名為“save_image”,具體代碼如下:任務(wù)實(shí)施3解析詳情頁數(shù)據(jù)#保存下載的圖片defsave_image(content):file_path='{0}/{1}.{2}'.format("D://image",md5(content).hexdigest(),'jpg')ifnotos.path.exists(file_path):withopen(file_path,'wb')asf:f.write(content)f.close()3、獲取并下載視頻如果遇到包含視頻的文章,則需要下載視頻,如圖1-23所示,網(wǎng)頁中的視頻鏈接在<link>標(biāo)簽里面的href屬性中,這里采用正則表達(dá)式獲取視頻鏈接。任務(wù)實(shí)施3解析詳情頁數(shù)據(jù)movie_pattern=pile('<link.*?hrefLang="zh-CN".*?href="(.*?)".*?>',re.S)movies=re.findall(movie_pattern,content)formovieinmovies:download_movie(movie,title)在“parse_page_detial”方法中添加如下代碼:其中“download_movie”方法用于下載圖片,具體代碼如下:任務(wù)實(shí)施3解析詳情頁數(shù)據(jù)defdownload_movie(url,title):print('正在下載視頻',url)#下載到本地
dl=DownloadMovie()dl.download(url,title)DownloadMovie類實(shí)現(xiàn)方法參見書2.3節(jié)本任務(wù)從網(wǎng)頁爬取下來的數(shù)據(jù)除了圖片和視頻外,還有“title”、圖片鏈接、視頻鏈接和網(wǎng)站的網(wǎng)址。因此需要將這些信息保存到MongoDB中。本任務(wù)將需要存儲(chǔ)的數(shù)據(jù)以字典形式返回,在“parse_page_detial”方法中添加如下代碼:任務(wù)實(shí)施4數(shù)據(jù)保存return{"title":title,"images":images,"movie":movies,"url":url}將數(shù)據(jù)保存到MongoDB中,需要獲取MongoDB的連接客戶端,具體代碼如下:任務(wù)實(shí)施4數(shù)據(jù)保存importpymongo#連接mongo數(shù)據(jù)庫False是因?yàn)槎噙M(jìn)程下頻繁的連接會(huì)報(bào)錯(cuò)client=pymongo.MongoClient(MONGO_URL,connect=False)db=client[MONGO_DB]然后創(chuàng)建“save_to_mongo”方法用于數(shù)據(jù)保存,并在主程序方法中調(diào)用即可,具體代碼如下:#保存到數(shù)據(jù)庫defsave_to_mongo(result):ifdb[MONGO_TABLE].insert(result):print('存儲(chǔ)成功',result)returnTruereturnFalse以上程序中用到的相關(guān)參數(shù)信息如下:任務(wù)實(shí)施4數(shù)據(jù)保存MONGO_URL='localhost'MONGO_DB='toutiao'MONGO_TABLE='toutiao'以上所有方法編寫完成后,還需要編寫一個(gè)主程序方法用于運(yùn)行程序,具體代碼如下:任務(wù)實(shí)施4數(shù)據(jù)保存frommultiprocessingimportPooldefmain(offset):keyword="街拍"html=get_page_index(offset,keyword)ifhtml:forurlinget_page_url(html):content=get_page_detial(url)ifcontent:result=parse_page_detial(content,url)ifresult:save_to_mongo(result)if__name__=='__main__':groups=[x*20forxinrange(START_PAGE,END_PAGE+1)]pool=Pool()pool.map(main,groups)請(qǐng)采用Ajax爬蟲方式爬取微博相關(guān)數(shù)據(jù)課后習(xí)題任務(wù)1.3京東動(dòng)態(tài)渲染頁面的信息爬取任務(wù)描述爬取的是京東“python爬蟲”書籍頁面所有關(guān)鍵的內(nèi)容,如下圖所示。我們需要模擬在搜索框中輸入關(guān)鍵詞,然后點(diǎn)擊搜索按鈕,獲取首頁的內(nèi)容。模擬點(diǎn)擊翻頁,或者輸入翻頁,獲取后續(xù)的頁面。獲取網(wǎng)頁的源代碼后,再分析獲取目標(biāo)數(shù)據(jù)的信息,并存儲(chǔ)到MongoDB數(shù)據(jù)庫。搜索關(guān)鍵字分析頁面并翻頁分析提取商品內(nèi)容信息保存至MongoDB任務(wù)目標(biāo)1
網(wǎng)頁結(jié)構(gòu)分析打開京東網(wǎng)站(/),在搜索輸入框中輸入關(guān)鍵詞“python爬蟲”,點(diǎn)擊搜索,進(jìn)入該項(xiàng)目要爬取的網(wǎng)頁,如圖1-25所示。其中我們主要爬取的數(shù)據(jù)信息包括:書籍名稱,價(jià)格,評(píng)價(jià)數(shù),出版社。任務(wù)實(shí)施圖1-25京東書籍信息頁面2安裝第三方庫本項(xiàng)目利用到的庫包括PyMongo、selenium、PyQuery;使用到了MongoDB工具,以及ChromeDriver驅(qū)動(dòng)。如下圖所示,安裝selenium、ChromeDriver驅(qū)動(dòng)等。任務(wù)實(shí)施圖chromedriver安裝驗(yàn)證成功圖
庫安裝方式3搜索關(guān)鍵字搜索關(guān)鍵字即利用selenium驅(qū)動(dòng)瀏覽器搜索關(guān)鍵字,得到查詢后的商品列表。任務(wù)實(shí)施圖
搜索按鈕的選擇器信息的獲取過程4
分析頁面并翻頁模擬搜索關(guān)鍵詞后,進(jìn)入商品列表首頁。在此我們通過Selenium模擬翻頁,得到后續(xù)頁面的商品列表。任務(wù)實(shí)施圖網(wǎng)頁頁碼顯示信息5
分析提取商品內(nèi)容提取商品內(nèi)容模塊我們利用PyQuery分析源碼,解析得到商品列表。其中我們主要爬取的是每一本“python爬蟲”書籍?dāng)?shù)據(jù)信息:書籍名稱,價(jià)格,評(píng)價(jià)數(shù),出版社。如圖所示。任務(wù)實(shí)施圖1-46書籍信息6
信息保存至MongoDB將商品列表信息存儲(chǔ)到數(shù)據(jù)庫MongoDB中。任務(wù)實(shí)施圖
存儲(chǔ)到MongoDB成功網(wǎng)絡(luò)爬蟲項(xiàng)目實(shí)戰(zhàn)感謝觀看主講人:xxx網(wǎng)絡(luò)爬蟲項(xiàng)目實(shí)戰(zhàn)項(xiàng)目二:特殊網(wǎng)頁數(shù)據(jù)獲取主講人:xxx231任務(wù)2.2古詩詞網(wǎng)數(shù)據(jù)爬取
任務(wù)2.1數(shù)睿思網(wǎng)模擬登錄任務(wù)2.3微信網(wǎng)頁代理爬蟲文章信息目錄任務(wù)2.1數(shù)睿思網(wǎng)模擬登錄任務(wù)描述表單登錄是指通過編寫程序模擬瀏覽器向服務(wù)器端發(fā)送POST請(qǐng)求,提交登錄需要的表單數(shù)據(jù),獲得服務(wù)器端認(rèn)可,返回需要的結(jié)果,從而實(shí)現(xiàn)模擬登錄。使用表單登錄的方法模擬登錄數(shù)睿思網(wǎng)站。網(wǎng)址::444/oauth/authorize?response_type=code&redirect_uri=https%3A%2F%2F%3A10010%2Fcallback&client_id=5f9285dc-c645-4d5d-9eb8-b18a024d15f3掌握使用Requests庫實(shí)現(xiàn)請(qǐng)求掌握使用Chrome開發(fā)者工具查找模擬登錄需要的相關(guān)信息掌握表單登錄的流程任務(wù)目標(biāo)1.1查找提交入口提交入口指的是登錄網(wǎng)頁(類似圖2-1)的表單數(shù)據(jù)(如用戶名、密碼等)的真實(shí)提交地址,它不一定是登錄網(wǎng)頁的地址,出于安全需要它可能會(huì)被設(shè)計(jì)成其他地址。找到表單數(shù)據(jù)的提交入口是表單登錄的前提。提交入口的請(qǐng)求方法大多數(shù)情況下是POST,因?yàn)橛脩舻牡卿洈?shù)據(jù)是敏感數(shù)據(jù),使用POST請(qǐng)求方法能夠避免用戶提交的登錄數(shù)據(jù)在瀏覽器端被泄露,從而保障數(shù)據(jù)的安全性。因此,請(qǐng)求方法是否為POST可以作為判斷提交入口的依據(jù)。(1)打開網(wǎng)站,單擊右上角的“登錄”按鈕,進(jìn)入登錄頁面,如圖2-1所示。任務(wù)實(shí)施圖2-1登錄頁面1.1查找提交入口(2)打開Chrome開發(fā)者工具后打開網(wǎng)絡(luò)面板,勾選“Preservelog”(保持日志)復(fù)選框,按“F5”鍵刷新網(wǎng)頁顯示各項(xiàng)資源,如圖2-2所示。任務(wù)實(shí)施圖2-2顯示各項(xiàng)資源1.1查找提交入口(3)在登錄頁面輸入賬號(hào)、密碼,單擊“登錄”按鈕,提交表單數(shù)據(jù),此時(shí)Chrome開發(fā)者工具會(huì)加載新的資源。(4)觀察Chrome開發(fā)者工具左側(cè)的資源,找到“authorize”資源并單擊,觀察右側(cè)的“Headers”標(biāo)簽下的“General”信息,如圖2-3所示,可發(fā)現(xiàn)“RequestMethod”的信息為“POST”,即請(qǐng)求方法為POST,可以判斷“RequestURL”的信息即為提交入口。任務(wù)實(shí)施圖2-3Chrome開發(fā)者工具獲取到的提交入口1.2查找并獲取需要提交的表單數(shù)據(jù)在1.1中,使用Chrome開發(fā)者工具可獲取提交入口,在“Headers”標(biāo)簽中,“FormData”信息為服務(wù)器端接收到的表單數(shù)據(jù),如圖2-4所示,其中,“username”表示賬寫,password”表示密碼,“redirect_urli”表示跳轉(zhuǎn)網(wǎng)址。redirect_url由系統(tǒng)自動(dòng)生成并提交,它在登錄網(wǎng)頁時(shí)無須輸入。任務(wù)實(shí)施圖2-4Chrome開發(fā)者工具獲取到的表單數(shù)據(jù)1.3使用POST請(qǐng)求方法登錄POST請(qǐng)求方法能夠保障用戶端提交數(shù)據(jù)的安全性,因此它被一般需要登錄的網(wǎng)站采用。Requests庫的post函數(shù)能夠以POST請(qǐng)求方法向服務(wù)器端發(fā)送請(qǐng)求,它返回一個(gè)Response<Response>對(duì)象。post函數(shù)的基本語法格式如下:requests.post(url,data=None,json=None,**kwargs)任務(wù)實(shí)施參數(shù)說明url接收string。表示提交入口。無默認(rèn)值data接收dict。表示需要提交的表單數(shù)據(jù)。無默認(rèn)值使用表單登錄的方法模擬登錄“筆趣閣”網(wǎng)站。網(wǎng)址為“/login.html”,登錄頁如下圖所示。實(shí)踐訓(xùn)練圖2-6筆趣閣任務(wù)2.2古詩詞網(wǎng)數(shù)據(jù)爬取任務(wù)描述在機(jī)器視覺領(lǐng)域,字符識(shí)別扮演著重要的角色,它可以利用計(jì)算機(jī)自動(dòng)識(shí)別字符。對(duì)于圖像中的字符,人類能夠輕松地閱讀,然而機(jī)器閱讀卻非常困難。驗(yàn)證碼技術(shù)就是基于這種人類能正常閱讀而機(jī)器無法讀取的圖片。當(dāng)網(wǎng)絡(luò)爬蟲采集數(shù)據(jù)時(shí),一旦遇到驗(yàn)證碼就無法提取里面的字符信息。在項(xiàng)目二的任務(wù)1中,我們講了如何通過表單來實(shí)現(xiàn)模擬登錄,登錄需要用戶名、密碼,但往往很多網(wǎng)頁相對(duì)比較復(fù)雜,登錄還需要輸入驗(yàn)證碼,本任務(wù)我們主要講驗(yàn)證碼的識(shí)別,古詩詞網(wǎng)登錄頁如圖2-7所示。網(wǎng)址:/user/login.aspx?from=/user/collect.aspx會(huì)安裝Tesseract工具,會(huì)配置環(huán)境熟悉PIL和tesseract庫能夠利用pytesseract識(shí)別簡(jiǎn)單的圖形驗(yàn)證碼任務(wù)目標(biāo)2.1Tesseract引擎的下載和安裝Tesseract是一個(gè)開源的OCR庫,是目前公認(rèn)的最優(yōu)秀、最精確的開源OCR系統(tǒng),具有準(zhǔn)確度高、靈活性高等特點(diǎn)。它不僅可以通過訓(xùn)練識(shí)別出任何字體(只要字體的風(fēng)格保持不變即可),而且還可以識(shí)別處任何Unicode字符。Tesseract支持60種以上的語言,它提供了一個(gè)引擎和命令行工具。要想在Windows系統(tǒng)下使用Tesseract,需要先安裝Tesseract-OCR引擎,可以從網(wǎng)址/UB-Mannheim/tesseract/wiki進(jìn)行下載,如圖2-8所示。任務(wù)實(shí)施圖2-8Tesseract-OC下載頁2.1Tesseract引擎的下載和安裝下載完成后,雙擊安裝文件,按照默認(rèn)設(shè)置進(jìn)行安裝。默認(rèn)情況下,安裝文件會(huì)為其配置系統(tǒng)環(huán)境變量,以指向安裝目錄。這樣,就可以在任意目錄下使用tesseract命令運(yùn)行。如果沒有配置環(huán)境變量,可以手動(dòng)進(jìn)行設(shè)置,默認(rèn)安裝目錄為:C:\ProgramFiles(x86)\Tesseract-OCR打開命令行窗口,輸入tesseract命令進(jìn)行驗(yàn)證。如果安裝成功,則會(huì)輸出如圖2-9所示的信息。任務(wù)實(shí)施2-9安裝Tesseract-OCR成功2.2第三方庫的安裝Tesseract是一個(gè)命令行工,安裝后只能通過tesseract命令在Python的外部運(yùn)行,而不能通過import語句引入使用,為了解決上述問題,Python提供了支持Tesseract-OCR引擎的Python版本的庫pytesseract。安裝pytesseract需要遵守如下要求:Python的版本必須是
python2.5+或
python3.x安裝
Python的圖像處理庫PIL(或Pillow)安裝谷歌的OCR識(shí)別引擎
Tesseract-OCR任務(wù)實(shí)施2.3驗(yàn)證碼識(shí)別1.獲取生成驗(yàn)證碼的圖片地址(1)打開網(wǎng)站,進(jìn)入登錄網(wǎng)頁,打開Chrome開發(fā)者工具后打開網(wǎng)絡(luò)面板,按“F5”鍵刷新網(wǎng)頁。(2)觀察Chrome開發(fā)者工具左側(cè)的資源,找到“RandCode.ashx”資源并單擊,觀察右側(cè)的Preview標(biāo)簽,若顯示驗(yàn)證碼圖片如左圖所示,則“RandCode.ashx”資源的RequestURL信息為驗(yàn)證碼圖片的地址,如圖2-10所示。任務(wù)實(shí)施圖2-11Chrome開發(fā)者工具獲取到的驗(yàn)證碼圖片2.3驗(yàn)證碼識(shí)別任務(wù)實(shí)施圖2-12驗(yàn)證碼圖片對(duì)應(yīng)的驗(yàn)證碼地址2.3驗(yàn)證碼識(shí)別任務(wù)實(shí)施2.將驗(yàn)證碼圖片下載到本地獲取驗(yàn)證碼圖片地址后,下一步對(duì)圖片地址發(fā)送請(qǐng)求,將圖片下載到本地。3.驗(yàn)證碼識(shí)別最后識(shí)別驗(yàn)證碼。使用PIL庫的Image模塊可以自動(dòng)調(diào)用本機(jī)的圖片查看程序打開驗(yàn)證碼圖片,效率更高。Image模塊自動(dòng)打開圖片分為兩步:使用open方法創(chuàng)建一個(gè)Image對(duì)象;使用show方法顯示圖片。open方法和show方法的基本語法格式如下。Image.open(fp,mode='r')Image.show(title=None,command=None)方法參數(shù)名稱說明openfp接收string。表示圖片路徑地址。無默認(rèn)值showtitle接收string。表示圖片標(biāo)題。一般默認(rèn)為None2.4完成登錄任務(wù)實(shí)施在任務(wù)1中,我們?cè)敿?xì)介紹了模擬登錄,古詩詞網(wǎng)登錄除了需要email、pwd外,還需要__VIEWSTATE、__VIEWSTATEGENERATOR、from、code、denglu等字段,如圖2-15所示。圖2-15Chrome開發(fā)者工具獲取到的表單數(shù)據(jù)通過人工識(shí)別驗(yàn)證碼登錄“千千小說網(wǎng)”網(wǎng)站。網(wǎng)址為“https://www.77xsw.cc/login.php”,登錄頁如下圖所示。實(shí)踐訓(xùn)練圖2-18千千小說網(wǎng)登錄頁任務(wù)2.3微信網(wǎng)頁代理爬蟲文章信息任務(wù)描述搜狗(sogo)網(wǎng)站(/)提供了“微信”模塊,即sogo爬取了微信文章信息和公眾號(hào)的信息,如圖所示。但是sogo具有很多反爬蟲的措施,會(huì)檢測(cè)到訪問IP異常,進(jìn)而封鎖IP。本任務(wù)主要講解利用代理來爬取sogo“微信”模塊中關(guān)于“程序員”的微信文章信息,包括:文章名字、文章內(nèi)容,并將爬取的信息保存到MongoDB中。圖2-19搜狗微信模塊使用Flask+Redis維護(hù)代理池抓取索引頁內(nèi)容設(shè)置代理分析詳情頁內(nèi)容保存數(shù)據(jù)信息至mongoDB任務(wù)目標(biāo)1
網(wǎng)頁結(jié)構(gòu)分析打開sogo網(wǎng)站的微信網(wǎng)頁(/),在搜索輸入框中輸入關(guān)鍵詞“程序員”,點(diǎn)擊“搜文章”按鈕,進(jìn)入該項(xiàng)目要爬取的網(wǎng)頁,如圖所示。其中我們主要爬取的數(shù)據(jù)信息包括:文章名字、文章內(nèi)容。任務(wù)實(shí)施圖
微信網(wǎng)頁信息2使用Flask+Redis維護(hù)代理池當(dāng)在爬取微信文章時(shí),可能出現(xiàn)驗(yàn)證碼識(shí)別頁面,此時(shí)是IP被封,網(wǎng)頁請(qǐng)求由200變成302的錯(cuò)誤狀態(tài),這種情況可以使用代理偽裝IP,完成爬蟲請(qǐng)求。但是互聯(lián)網(wǎng)上公開的大量免費(fèi)代理,有好有壞,需要對(duì)大量代理進(jìn)行維護(hù),剔除沒有用的代理。在對(duì)微信文章列表爬取時(shí),我們可能會(huì)需要非常多的IP,在此我們需要維護(hù)一個(gè)代理池,代理池是通過爬取各個(gè)免費(fèi)的代理資源中的代理IP信息,存儲(chǔ)到本地,然后進(jìn)行驗(yàn)證是否可用,并維護(hù)可用代理IP列表,最后在需要使用的時(shí)候取出代理IP,任務(wù)實(shí)施圖代理內(nèi)容展示3抓取索引頁內(nèi)容創(chuàng)建項(xiàng)目,命名為Weixin_Spider,然后創(chuàng)建一個(gè)python文件fan_spider.py。在本節(jié)中完成索引頁的爬取,利用requests請(qǐng)求目標(biāo)站點(diǎn),得到索引頁HTML代碼,返回文章列表。任務(wù)實(shí)施圖html網(wǎng)頁代碼4
設(shè)置代理如果遇到302狀態(tài)碼,則證明IP被封,需要切換到代理,進(jìn)行重試。任務(wù)實(shí)施5
分析詳情頁內(nèi)容獲得索引頁后,請(qǐng)求詳情頁中的文章超鏈接,訪問鏈接,分析文章內(nèi)容頁面,得到數(shù)據(jù)信息:文章名字、文章內(nèi)容。任務(wù)實(shí)施圖獲取的文章信息6
保存數(shù)據(jù)信息至mongoDB將商品列表信息存儲(chǔ)到數(shù)據(jù)庫MongoDB中。任務(wù)實(shí)施網(wǎng)絡(luò)爬蟲項(xiàng)目實(shí)戰(zhàn)感謝觀看主講人:xxx網(wǎng)絡(luò)爬蟲項(xiàng)目實(shí)戰(zhàn)項(xiàng)目三:scrapy框架爬蟲主講人:xxx231任務(wù)2.2登錄趕集網(wǎng)任務(wù)2.1當(dāng)當(dāng)網(wǎng)商品爬取任務(wù)2.3失信人信息爬取目錄任務(wù)2.1當(dāng)當(dāng)網(wǎng)商品爬取任務(wù)描述本任務(wù)通過抓取失信人名稱、失信人號(hào)碼、法人(企業(yè))、年齡(企業(yè)的年齡為0)、區(qū)域、失信內(nèi)容、公布日期、公布執(zhí)行單位、創(chuàng)建日期和更新日期等信息,并將抓取的數(shù)據(jù),統(tǒng)一存儲(chǔ)到MySQL數(shù)據(jù)庫中以供后續(xù)分析使用。獲取百度失信人名單將名單信息保存到MySQL數(shù)據(jù)庫中實(shí)現(xiàn)隨機(jī)User-Agent下載器中間件實(shí)現(xiàn)代理IP下載器中間件任務(wù)目標(biāo)1創(chuàng)建Scrapy項(xiàng)目首先進(jìn)入cmd命令窗口,然后進(jìn)入本地磁盤中的項(xiàng)目保存目錄(該目錄自己選定),如圖3-2所示:任務(wù)實(shí)施1創(chuàng)建爬蟲項(xiàng)目使用Scrapy命令新建項(xiàng)目名為“dangdang”的項(xiàng)目,命令如下:任務(wù)實(shí)施scrapystartprojectdangdang此時(shí)在項(xiàng)目保存目錄多了一個(gè)項(xiàng)目名為“dangdang”的項(xiàng)目,如圖3-3所示1創(chuàng)建爬蟲項(xiàng)目cd進(jìn)入“dangdang”項(xiàng)目目錄,并基于“basic模板”創(chuàng)建爬蟲文件,命令如下:任務(wù)實(shí)施scrapygenspider-tbasicdd可以看到在項(xiàng)目根目錄的“dangdang”目錄下面的“spiders”創(chuàng)建了名為“dd”的爬蟲文件,如圖3-4所示:2商品數(shù)據(jù)爬取1、安裝XPath插件打開谷歌瀏覽器,點(diǎn)擊右上角的圖表,選擇“更多工具”里的“擴(kuò)展程序”,如圖3-5所示任務(wù)實(shí)施2商品數(shù)據(jù)爬取1、安裝XPath插件然后會(huì)彈出如圖3-6所示的對(duì)話框,點(diǎn)擊“擴(kuò)展程序”,會(huì)彈出如圖3-7所示彈框,點(diǎn)擊“打開Chrome網(wǎng)上應(yīng)用店”按鈕,進(jìn)入網(wǎng)上應(yīng)用店任務(wù)實(shí)施2商品數(shù)據(jù)爬取1、安裝XPath插件最后在右上角的輸入框中輸入需要安裝插件的名稱,如圖3-8所示,搜索擴(kuò)展程序任務(wù)實(shí)施2商品數(shù)據(jù)爬取1、安裝XPath插件在搜索結(jié)果中找到如圖3-9所示的XPath插件,并將其添加至谷歌瀏覽器中。任務(wù)實(shí)施2商品數(shù)據(jù)爬取
2、定義爬取內(nèi)容使用PyCharm打開剛剛創(chuàng)建好的項(xiàng)目。首先在items.py文件中定義需要爬取的內(nèi)容,本任務(wù)需要爬取商品名稱“title”、商品鏈接“l(fā)ink”和商品評(píng)論數(shù)“comment”三個(gè)數(shù)據(jù),代碼如下:任務(wù)實(shí)施importscrapyclassDangdangItem(scrapy.Item):#definethefieldsforyouritemherelike:#name=scrapy.Field()title=scrapy.Field()#商品名
link=scrapy.Field()#商品鏈接
comment=scrapy.Field()#商品評(píng)論數(shù)2商品數(shù)據(jù)爬取
3、編寫爬蟲代碼觀察當(dāng)當(dāng)網(wǎng)商品頁,可以看到商品頁的內(nèi)容不止一頁,而是有79頁,而每一頁都有對(duì)應(yīng)的網(wǎng)址,而網(wǎng)址的變化是有規(guī)律的,如圖3-11所示,當(dāng)查看第1頁時(shí),網(wǎng)址為/pg1-cid4008154.html,而查看第2頁時(shí)網(wǎng)址為/pg2-cid4008154.html,以此類推,變化的只是網(wǎng)址中的“pg”后面的數(shù)字而已。因此爬蟲文件dd.py中的“start_urls”應(yīng)該為第1頁的網(wǎng)址。任務(wù)實(shí)施2商品數(shù)據(jù)爬取
3、編寫爬蟲代碼在dd.py爬蟲文件中編寫如下代碼:任務(wù)實(shí)施importscrapyclassDdSpider(scrapy.Spider):name="dd"allowed_domains=[""]start_urls=['/pg1-cid4008154.html']2商品數(shù)據(jù)爬取
3、編寫爬蟲代碼如圖3-12所示按F12查看網(wǎng)址源碼,可以看到商品的名稱信息和鏈接是在<a>標(biāo)簽中的“title”和“href”屬性表示:任務(wù)實(shí)施2商品數(shù)據(jù)爬取
3、編寫爬蟲代碼本任務(wù)采用XPath表達(dá)式匹配需要爬取的內(nèi)容,為了精準(zhǔn)匹配,需要選擇<a>標(biāo)簽中屬性“name='itemlist-title'”和“ame='sort-evaluate'”輔助進(jìn)行定位。同時(shí)需要將爬取下來的內(nèi)容存放到上一步定義的變量中,所以需要導(dǎo)入items里面的DangdangItem類,代碼如下:任務(wù)實(shí)施#導(dǎo)入items里面的DangdangItem類fromdangdang.itemsimportDangdangItem#在DdSpider類中定義回調(diào)函數(shù)
defparse(self,response):item=DangdangItem()item["title"]=response.xpath("http://a[@name='itemlist-title']/@title").extract()item["link"]=response.xpath("http://a[@name='itemlist-title']/@href").extract()item["comment"]=response.xpath("http://a[@name='itemlist-review']/text()").extract()print(item["title"])2商品數(shù)據(jù)爬取
3、編寫爬蟲代碼接下來在cmd窗口中運(yùn)行爬蟲文件進(jìn)行測(cè)試,代碼如下:任務(wù)實(shí)施scrapycrawldd--nolog3商品數(shù)據(jù)處理經(jīng)過上一步,已經(jīng)爬取到了商品的三個(gè)信息。但是在Scrapy項(xiàng)目中,數(shù)據(jù)爬取采用一個(gè)文件進(jìn)行爬取,而爬取后的數(shù)據(jù)又是交給另外一個(gè)文件即“pipelines.py”進(jìn)行處理的,因此在“dd.py”文件中需要使用“yield”進(jìn)行數(shù)據(jù)返回,代碼如下任務(wù)實(shí)施yielditem3商品數(shù)據(jù)處理Scrapy默認(rèn)是不開啟pipelines的,需要在“settings.py”文件中進(jìn)行開啟,找到pipelines的設(shè)置代碼,解除注釋即可,如圖3-14所示任務(wù)實(shí)施3商品數(shù)據(jù)處理開啟pipelines后,在pipelines.py文件中可以編寫相關(guān)代碼處理爬取后的數(shù)據(jù)。本任務(wù)將數(shù)據(jù)保存在MySQL數(shù)據(jù)庫中,因此需要引入第三方庫pymysql。在插入數(shù)據(jù)之前需要在數(shù)據(jù)庫中創(chuàng)建名為“dd”的數(shù)據(jù)庫,并且創(chuàng)建包含id(int)、title(varchar(50))、link(varchar(50))、comment(varchar(50))四個(gè)字段的表goods。數(shù)據(jù)存儲(chǔ)的具體代碼如下:任務(wù)實(shí)施importpymysqlclassDangdangPipeline(object):defprocess_item(self,item,spider):#連接databaseconn=pymysql.connect(host="localhost",user="root",password="root",database="dd")#得到一個(gè)可以執(zhí)行SQL語句的光標(biāo)對(duì)象
cursor=conn.cursor()foriinrange(0,len(item["title"])):title=item["title"][i]link=item["link"][i]comment=item["comment"][i]sql="insertintogoods(title,link,comment)values('"+title+"','"+link+"','"+comment+"');"try:#執(zhí)行SQL語句
cursor.execute(sql)#提交事務(wù)
mit()exceptExceptionaserr:pass#print(err)cursor.close()conn.close()returnitem3商品數(shù)據(jù)處理要實(shí)現(xiàn)翻頁只需要改變鏈接中的“pg”后面的數(shù)字即可,因此在dd.py文件中可以采用for循環(huán)繼續(xù)爬取數(shù)據(jù)。因?yàn)榈谝豁摰臄?shù)據(jù)我已經(jīng)爬取了,所以現(xiàn)在for循環(huán)中需要從第2頁開始爬取,到第79頁結(jié)束。任務(wù)實(shí)施fromscrapy.httpimportRequestforiinrange(2,80):url='/pg'+str(i)+'-cid4008154.html'yieldRequest(url,callback=self.parse)3商品數(shù)據(jù)處理運(yùn)行結(jié)果如圖3-15所示。任務(wù)實(shí)施在本任務(wù)的基礎(chǔ)上,爬取如圖3-16所示商品的價(jià)格信息和折扣信息課后練習(xí)任務(wù)2.2登錄趕集網(wǎng)任務(wù)描述本任務(wù)將以趕集網(wǎng)為例,介紹如何使用Scrapy框架實(shí)現(xiàn)通過輸入賬號(hào)、密碼和驗(yàn)證碼完成用戶登錄。使用Scrapy模擬登錄趕集網(wǎng)對(duì)隱藏式驗(yàn)證碼進(jìn)行獲取獲取趕集網(wǎng)驗(yàn)證碼并保存任務(wù)目標(biāo)1創(chuàng)建爬蟲項(xiàng)目首先進(jìn)入cmd命令窗口,然后進(jìn)入本地磁盤中的項(xiàng)目保存目錄(該目錄自己選定),如圖3-18所示:任務(wù)實(shí)施1創(chuàng)建爬蟲項(xiàng)目然后使用Scrapy命令新建項(xiàng)目名為“l(fā)ogin”的項(xiàng)目,命令如下:任務(wù)實(shí)施scrapystartprojectlogin此時(shí)在項(xiàng)目保存目錄多了一個(gè)項(xiàng)目名為“l(fā)ogin”的項(xiàng)目,如圖3-19所示。1創(chuàng)建爬蟲項(xiàng)目cd進(jìn)入“l(fā)ogin”項(xiàng)目目錄,并基于“basic模板”創(chuàng)建爬蟲文件,命令如下:任務(wù)實(shí)施scrapygenspider-tbasicganji行結(jié)果如圖3-20所示,可以看到在項(xiàng)目根目錄的“l(fā)ogin”目錄下面的“spiders”創(chuàng)建了名為“ganji.py”的爬蟲文件。1創(chuàng)建爬蟲項(xiàng)目創(chuàng)建好爬蟲項(xiàng)目后,用PyCharm打開,然后進(jìn)入到配置文件“settings.py”中,選擇不遵守Robot協(xié)議:任務(wù)實(shí)施#Robot協(xié)議不遵守ROBOTSTXT_OBEY=False然后,設(shè)置瀏覽器配置,該配置可以選擇自己瀏覽器的配置具體配置如下:#瀏覽器的配置USER_AGENT='Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/88.0.4324.190Safari/537.36'2獲取表單HashCode當(dāng)你輸入的用戶名或者密碼錯(cuò)誤的時(shí)候,頁面中將多出一個(gè)驗(yàn)證碼和驗(yàn)證碼輸入框,如圖3-20所示。任務(wù)實(shí)施2獲取表單HashCode通過瀏覽器的抓包工具進(jìn)行抓包,點(diǎn)擊以字符串“l(fā)ogin.php”開頭的鏈接,然后在“Heaers”欄目中可以查看登錄的Form表單數(shù)據(jù),如圖3-21所示,其中鍵名“_hash_”的值是隨機(jī)生產(chǎn)的,這個(gè)值在編寫代碼是需要從網(wǎng)頁中獲取任務(wù)實(shí)施2獲取表單HashCode查看網(wǎng)頁源碼,通過搜索“_hash_”,可以在網(wǎng)頁中找到圖3-21所示“_hash_”鍵對(duì)應(yīng)的值,而且如圖3-22所示,整個(gè)頁面中只有一個(gè),所以我們可以用正則表達(dá)式“__hash__":"(.+)”進(jìn)行獲取任務(wù)實(shí)施3獲取驗(yàn)證碼通過定位元素,可以得到驗(yàn)證碼的XPath表達(dá)式為“//label[@class="label-imgcode"]/img[@class="login-img-checkcode"]/@src”。任務(wù)實(shí)施取驗(yàn)證碼不需要使用XPath表達(dá)式,而是直接使用固定鏈接“/ajax.php?dir=captcha&module=login_captcha”即可4代碼編寫在項(xiàng)目“spiders”目錄下面的“ganji.py”文件中下面編寫如下代碼任務(wù)實(shí)施classGanjiSpider(scrapy.Spider):name='ganji'allowed_domains=['']start_urls=['/login.php']defparse(self,response):hash_code=re.findall(r'"__hash__":"(.+)"',response.text)[0]img_url='/ajax.php?dir=captcha&module=login_captcha'yieldscrapy.Request(img_url,callback=self.parse_info,meta={'hash_code':hash_code})4代碼編寫在“ganji.py”文件中創(chuàng)建“parse_info”函數(shù),具體代碼如下任務(wù)實(shí)施defparse_info(self,response):hash_code=response.request.meta['hash_code']withopen('yzm.jpg','wb')asf:f.write(response.body)code=input("請(qǐng)輸入驗(yàn)證碼:")form_data={"username":"lijiantiansheng","password":"abc123456","setcookie":"0","checkCode":code,"next":"/","source":"passport","__hash__":hash_code}login_url='/login.php'yieldscrapy.FormRequest(login_url,callback=self.after_login,formdata=form_data)4代碼編寫上面的代碼將獲取到的驗(yàn)證碼圖片直接保存在項(xiàng)目根目錄,然后通過手動(dòng)輸入的方式存入字典變量“form_data”?!癴orm_data”變量就是模擬登錄是需要提交的表單數(shù)據(jù),表單中需要那些字段可以參見圖3-21。回調(diào)函數(shù)為“after_login”,具體代碼如下:任務(wù)實(shí)施defafter_login(self,response):print(response.text)4代碼編寫使用“scrapycrawlganji”運(yùn)行程序,驗(yàn)證碼會(huì)自動(dòng)存儲(chǔ)到項(xiàng)目根目錄中,如圖3-24所示。然后手動(dòng)輸入驗(yàn)證碼,如圖3-25所示,按回車鍵即可成功運(yùn)行程序。任務(wù)實(shí)施4代碼編寫出現(xiàn)如圖3-26所示的結(jié)果,并且不報(bào)錯(cuò),說明登錄成功。任務(wù)實(shí)施4代碼編寫請(qǐng)使用scrapy框架完成飛盧小說網(wǎng)的模擬登錄課后習(xí)題任務(wù)2.3失信人信息爬取任務(wù)描述本任務(wù)通過抓取失信人名稱、失信人號(hào)碼、法人(企業(yè))、年齡(企業(yè)的年齡為0)、區(qū)域、失信內(nèi)容、公布日期、公布執(zhí)行單位、創(chuàng)建日期和更新日期等信息,并將抓取的數(shù)據(jù),統(tǒng)一存儲(chǔ)到MySQL數(shù)據(jù)庫中以供后續(xù)分析使用。獲取百度失信人名單將名單信息保存到MySQL數(shù)據(jù)庫中實(shí)現(xiàn)隨機(jī)User-Agent下載器中間件實(shí)現(xiàn)代理IP下載器中間件任務(wù)目標(biāo)1創(chuàng)建爬蟲項(xiàng)目首先進(jìn)入cmd命令窗口,然后進(jìn)入本地磁盤中的項(xiàng)目保存目錄(該目錄自己選定),如圖3-30所示:任務(wù)實(shí)施1創(chuàng)建爬蟲項(xiàng)目然后使用Scrapy命令新建項(xiàng)目名為“dishonest”的項(xiàng)目,命令如下:任務(wù)實(shí)施scrapystartprojectdishonest此時(shí)在項(xiàng)目保存目錄多了一個(gè)項(xiàng)目名為“dishonest”的項(xiàng)目,如圖3-31所示2定義數(shù)據(jù)模型在items.py文件中定義數(shù)據(jù)模型類DishonestItem,繼承scrapy.Item。然后定義如下要抓取字段:①失信人名稱②失信人號(hào)碼③失信人年齡④區(qū)域⑤法人(企業(yè))⑥失信內(nèi)容⑦公布日期⑧公布/執(zhí)行單位⑨創(chuàng)建日期⑩更新日期任務(wù)實(shí)施2定義數(shù)據(jù)模型實(shí)現(xiàn)代碼如下:任務(wù)實(shí)施classDishonestItem(scrapy.Item):#definethefieldsforyouritemherelike:#姓名/獲取企業(yè)名稱
name=scrapy.Field()#證件號(hào)
card_num=scrapy.Field()#年齡
age=scrapy.Field()#區(qū)域
area=scrapy.Field()#失信內(nèi)容
content=scrapy.Field()#法人
business_entity=scrapy.Field()#公布單位/執(zhí)行單位
publish_unit=scrapy.Field()#公布日期/宣判日期
publish_date=scrapy.Field()#更新日期,創(chuàng)建日期
create_date=scrapy.Field()#更新日期
update_date=scrapy.Field()3爬取失信人名單打開百度,搜索關(guān)鍵詞“失信人”,然后打開開發(fā)人員工具,點(diǎn)擊翻頁按鈕,可以得到如上圖所示請(qǐng)求鏈接。任務(wù)實(shí)施3爬取失信人名單拷貝URL到瀏覽器中,發(fā)現(xiàn)請(qǐng)求不成功。通過測(cè)試,發(fā)現(xiàn)請(qǐng)求是需要添加User-Agent和Referer兩個(gè)請(qǐng)求頭。使用Pycharm打開上一步新建的項(xiàng)目文件,在settings.py文件中,設(shè)置如下請(qǐng)求頭:任務(wù)實(shí)施DEFAULT_REQUEST_HEADERS={'Referer':'/s','User-Agent':'Mozilla/5.0(Macintosh;IntelMacOSX10_14_1)AppleWebKit/537.36(KHTML,likeGecko)Chrome/70.0.3538.110Safari/537.36'}3爬取失信人名單cd進(jìn)入“dishonest”項(xiàng)目目錄,并基于“basic模板”創(chuàng)建爬蟲文件,命令如下任務(wù)實(shí)施scrapygenspider-tbasicbaidu可以看到在項(xiàng)目根目錄的“dishonest”目錄下面的“spiders”創(chuàng)建了名為“baidu”的爬蟲文件,如下圖所示:3爬取失信人名單在settings.py文件中,關(guān)閉robots協(xié)議,如下圖所示:任務(wù)實(shí)施3爬取失信人名單請(qǐng)求地址如下:任務(wù)實(shí)施/8aQDcjqpAAV3otqbppnN2DJv/api.php?resource_id=6899&query=%E5%A4%B1%E4%BF%A1%E4%BA%BA&pn=10&rn=10&from_mid=1&ie=utf-8&oe=utf-8&format=json&t=1629533759089&cb=jQuery11020859892984746842_1629533609307&_=1629533609308通過對(duì)URL攜帶參數(shù)的分析,請(qǐng)求的URL必須攜帶如下參數(shù):①resource_id=6899:資源id,固定值。②query=失信人名單:查詢內(nèi)容,固定值。③pn=0:數(shù)據(jù)起始號(hào)碼。④rn=10:固定是10。⑤ie=utf-8&oe=utf-8:指定數(shù)據(jù)的編碼方式,固定值。⑥format=json:數(shù)據(jù)格式,固定值。3爬取失信人名單因此可以確定起始URL為:任務(wù)實(shí)施/8aQDcjqpAAV3otqbppnN2DJv/api.php?resource_id=6899&query=失信人&pn=0&rn=10&ie=utf-8&oe=utf-8請(qǐng)求返回?cái)?shù)據(jù)3爬取失信人名單點(diǎn)擊“Preview”,展開JSON格式的數(shù)據(jù),如圖上所示,可以看出,請(qǐng)求返回?cái)?shù)據(jù)的格式也是JSON類型的,而且其中有幾個(gè)參數(shù)和翻頁相關(guān),具體如下:dispNum:總的數(shù)據(jù)條數(shù)。listNum:總頁數(shù)。resNum:每頁數(shù)據(jù)條數(shù)。任務(wù)實(shí)施3爬取失信人名單根據(jù)上一步的分析的URL,只需要改變URL中的參數(shù)“pn”即可獲取不同頁面的數(shù)據(jù),如下圖所示,當(dāng)訪問第2頁時(shí),請(qǐng)求的URL中參數(shù)pn=10,以此類推。任務(wù)實(shí)施3爬取失信人名單實(shí)現(xiàn)翻頁首先需要先獲取總的數(shù)據(jù)條數(shù)“dispNum”,然后每隔10條數(shù)據(jù),構(gòu)建一個(gè)請(qǐng)求,具體代碼如下:任務(wù)實(shí)施
defparse(self,response):#構(gòu)建所有頁面請(qǐng)求
#把響應(yīng)內(nèi)容的json字符串,轉(zhuǎn)為字典
results=json.loads(response.text)#取出總數(shù)據(jù)條數(shù)
disp_num=jsonpath(results,'$..dispNum')[0]print(disp_num)#URL模板
url_pattern='/8aQDcjqpAAV3otqbppnN2DJv/api.php?resource_id=6899&query=失信人&pn={}&rn=10&ie=utf-8&oe=utf-8'#每隔10條數(shù)據(jù),構(gòu)建一個(gè)請(qǐng)求
forpninrange(0,disp_num,10):#構(gòu)建URLurl=url_pattern.format(pn)#創(chuàng)建請(qǐng)求,交給引擎
yieldscrapy.Request(url,callback=self.parse_data)3爬取失信人名單請(qǐng)求返回的數(shù)據(jù)對(duì)應(yīng)的key:任務(wù)實(shí)施3爬取失信人名單新建函數(shù)“parse_data”,并打印返回的數(shù)據(jù),如圖3-37所示,可以看出,數(shù)據(jù)是通過JSON格式存儲(chǔ)的,key為“result”。為了獲取數(shù)據(jù),需要導(dǎo)入第三方包“jsonpath”,jsonpath是xpath在json的應(yīng)用,可以通過xpath的方式獲取JSON數(shù)據(jù)。具體代碼如下:任務(wù)實(shí)施
defparse_data(self,response):"""解析數(shù)據(jù)"""#響應(yīng)數(shù)據(jù)
datas=json.loads(response.text)#print(datas)results=jsonpath(datas,'$..result')[0]#print(results)#遍歷結(jié)果列表
forresultinresults:item=DishonestItem()#失信人名稱
item['name']=result['iname']#失信人號(hào)碼
item['card_num']=result['cardNum']3爬取失信人名單任務(wù)實(shí)施
#失信人年齡
item['age']=int(result['age'])#區(qū)域
item['area']=result['areaName']#法人(企業(yè))item['business_entity']=result['businessEntity']#失信內(nèi)容
item['content']=result['duty']#公布日期
item['publish_date']=result['publishDate']#公布/執(zhí)行單位
item['publish_unit']=result['courtName']#創(chuàng)建日期
item['create_date']=datetime.now().strftime('%Y-%m-%d%H:%M:%S')#更新日期
item['update_date']=datetime.now().strftime('%Y-%m-%d%H:%M:%S')#print(item)#把數(shù)據(jù)交給引擎
yielditem4保存失信人名單信息任務(wù)實(shí)施第一步:在MySQL中創(chuàng)建數(shù)據(jù)庫:--創(chuàng)建數(shù)據(jù)庫createdatabasedishonest;4保存失信人名單信息任務(wù)實(shí)施第二步:創(chuàng)建表--創(chuàng)建表
createtabledishonest(dishonest_idINTNOTNULLAUTO_INCREMENT,--id主鍵
ageINTNOTNULL,--年齡,自然人年齡都是>0的,企業(yè)的年齡等于0nameVARCHAR(200)NOTNULL,--失信人名稱
card_numVARCHAR(50),--失信人號(hào)碼
areaVARCHAR(50)NOTNULL,--區(qū)域
contentVARCHAR(2000)NOTNULL,--失信內(nèi)容
business_entityVARCHAR(20),--企業(yè)法人
publish_unitVARCHAR(200),--發(fā)布單位
publish_dateVARCHAR(20),--發(fā)布單位
create_dateDATETIME,--創(chuàng)建日期
update_dateDATETIME,--更新日期
PRIMARYKEY(dishonest_id));;4保存失信人名單信息任務(wù)實(shí)施第三步:在settings.py文件中配置如下數(shù)據(jù)庫信息:#配置
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度智能家居音響系統(tǒng)與家裝室內(nèi)裝修合同9篇
- 二零二五版大理石瓷磚研發(fā)與銷售合作合同范本3篇
- 二零二五版民營(yíng)企業(yè)股權(quán)激勵(lì)合同書3篇
- 教育局教師幼兒園專項(xiàng)2025年度勞動(dòng)合同規(guī)范文本3篇
- 二零二五年銷售代理合同:汽車銷售代理及區(qū)域獨(dú)家合作協(xié)議2篇
- 2025年科技孵化器場(chǎng)地租賃保證金合同范本2篇
- 二零二五版39上公司兜底協(xié)議:綠色環(huán)保項(xiàng)目投資風(fēng)險(xiǎn)控制合同3篇
- 二零二五年度鋼箱梁橋工程施工廢棄物處理與回收利用合同3篇
- 二零二五版綠色建筑項(xiàng)目基礎(chǔ)勞務(wù)分包合同2篇
- 二零二五年度高速公路隧道防雷安全防護(hù)合同3篇
- 不銹鋼伸縮縫安裝施工合同
- 水土保持監(jiān)理總結(jié)報(bào)告
- Android移動(dòng)開發(fā)基礎(chǔ)案例教程(第2版)完整全套教學(xué)課件
- 醫(yī)保DRGDIP付費(fèi)基礎(chǔ)知識(shí)醫(yī)院內(nèi)培訓(xùn)課件
- 專題12 工藝流程綜合題- 三年(2022-2024)高考化學(xué)真題分類匯編(全國(guó)版)
- DB32T-經(jīng)成人中心靜脈通路裝置采血技術(shù)規(guī)范
- 【高空拋物侵權(quán)責(zé)任規(guī)定存在的問題及優(yōu)化建議7100字(論文)】
- TDALN 033-2024 學(xué)生飲用奶安全規(guī)范入校管理標(biāo)準(zhǔn)
- 物流無人機(jī)垂直起降場(chǎng)選址與建設(shè)規(guī)范
- 冷庫存儲(chǔ)合同協(xié)議書范本
- AQ/T 4131-2023 煙花爆竹重大危險(xiǎn)源辨識(shí)(正式版)
評(píng)論
0/150
提交評(píng)論