日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

实战|Python轻松实现动态网页爬虫(附详细源码)

發布時間:2024/9/15 python 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实战|Python轻松实现动态网页爬虫(附详细源码) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

用淺顯易懂的語言分享爬蟲、數據分析及可視化等干貨,希望人人都能學到新知識。

項目背景

事情是這樣的,前幾天我公眾號寫了篇爬蟲入門的實戰文章,叫做《實戰|手把手教你用Python爬蟲(附詳細源碼)》。發出去不到一天,一名從業10年的王律師找到了我,我雖然同意了他的微信申請,但內心是按奈不住的慌張。

簡單交流了下,原來他在自學爬蟲,但他發現翻頁的時候,url一直不變。其實他爬取的是較高難度的網頁,也就是這次要詳細介紹的動態網頁。一向樂于助人的J哥自然會給他指明方向,以最短的時間從青銅走向白銀。

AJAX動態加載網頁

什么是動態網頁

J哥一向注重理論與實踐相結合,知其然也要知其所以然,才能以不變應萬變。

所謂的動態網頁,是指跟靜態網頁相對的一種網頁編程技術。靜態網頁,隨著html代碼的生成,頁面的內容和顯示效果就基本上不會發生變化了——除非你修改頁面代碼。而動態網頁則不然,頁面代碼雖然沒有變,但是顯示的內容卻是可以隨著時間、環境或者數據庫操作的結果而發生改變的。——來源百度百科

動態網頁具有減少工作量、內容更新快、可完成功能多等特點,被很多公司所采用,比如狗東、某寶、某瓣、某乎等等。

什么是AJAX

隨著人們對動態網頁加載速度的要求越來越高,AJAX技術應運而生并成為許多站點的首選。AJAX是一種用于創建快速動態網頁的技術,通過在后臺與服務器進行少量數據交換,使網頁實現異步更新。這意味著在不重新加載整個網頁的情況下,可以對網頁的某部分進行更新。

如何爬取AJAX動態加載網頁

1. 解析接口

只要是有數據發送過來,那肯定是有發送到服務器的請求的吧。我們只需找出它悄悄加載出的頁面的真實請求即可。特點:爬取速度快,爬取的數據干凈,有些網站解析難度較大。

2. Selenium?

selenium是什么呢?它本來是個自動化測試工具,但是被廣泛的用戶拿去爬蟲了。它是一個工具,這個工具可以用代碼操作瀏覽器,比如控制瀏覽器的下滑、模擬鼠標點擊等。特點:代碼較簡單,爬取速度慢,容易被封ip。

項目實操

怎么說了那么多理論,說實話J哥也不想那么啰嗦。可是吧,這些東西經常會被問到,干脆直接寫下來,下次還有人問就直接把這篇文章發給他,一勞永逸!


OK,咱們繼續回到王律師的part。王律師作為一名資深律師,深知研究法院歷年公示的開庭信息、執行信息等對于提升業務能力具有重要作用。于是,他興高采烈地打開了一個法院信息公示網頁。

長這樣:

然后,他根據J哥之前寫的爬蟲入門文章去爬數據,成功提取了第一頁,內心無比之激動。

緊接著,他加了個for循環,想著花個幾分鐘時間把此網站2164頁共計32457條開庭公告數據提取到excel里。

然后,也就沒有然后了。各位看了前面的理論部分應該也知道了,他這是 AJAX動態加載的網頁。無論你怎么點擊下一頁,url是不會變化的。你不信我點給你看看,左上角的url像山一樣矗立在那:

解析接口

既然如此,那我們就開啟爬蟲的正確姿勢吧,先用解析接口的方法來寫爬蟲。

首先,找到真實請求。右鍵檢查,點擊Network,選中XHR,刷新網頁,選擇Name列表中的jsp文件。沒錯,就這么簡單,真實請求就藏在里面。

?

我們再仔細看看這個jsp,這簡直是個寶啊。有真實請求url,有請求方法post,有Headers,還有Form Data,而From Data表示給url傳遞的參數,通過改變參數,咱們就可以獲得數據!為了安全,我把自個Cookie打了個馬賽克,機智的朋友也許發現了我順帶給自個打了個廣告。

我們再仔細看看這些參數,pagesnum參數不就是代表頁數嘛!王律師頓悟,原來他心心念念的翻頁在這里!跨過千山萬水終于找到你!我們嘗試點擊翻頁,發現只有pagesnum參數會變化。

既然發現了它,那就趕緊抓住它。J哥以迅雷不及掩耳勢打開PyCharm,導入了爬蟲所需的庫。

1from?urllib.parse?import?urlencode 2import?csv 3import?random 4import?requests 5import?traceback 6from?time?import?sleep 7from?lxml?import?etree????#lxml為第三方網頁解析庫,強大且速度快

構造真實請求,添加Headers。這里J哥沒有貼自己的User-Agent和Cookie,主要是一向膽小甚微的J哥害怕啊。

1base_url?=?'http://www.hshfy.sh.cn/shfy/gweb2017/ktgg_search_content.jsp?'??#這里要換成對應Ajax請求中的鏈接23headers?=?{4????'Connection':?'keep-alive',5????'Accept':?'*/*',6????'X-Requested-With':?'XMLHttpRequest',7????'User-Agent':?'你的User-Agent',8????'Origin':?'http://www.hshfy.sh.cn',9????'Referer':?'http://www.hshfy.sh.cn/shfy/gweb2017/ktgg_search.jsp?zd=splc', 10????'Accept-Language':?'zh-CN,zh;q=0.9', 11????'Content-Type':?'application/x-www-form-urlencoded', 12????'Cookie':?'你的Cookie' 13}

構建get_page函數,自變量為page,也就是頁數。以字典類型創建表單data,用post方式去請求網頁數據。這里要注意要對返回的數據解碼,編碼為'gbk',否則返回的數據會亂碼!另外我還加了異常處理優化了下,以防意外發生。

1def?get_page(page):2????n?=?33????while?True:4????????try:5????????????sleep(random.uniform(1,?2))??#?隨機出現1-2之間的數,包含小數6????????????data?=?{7????????????????'yzm':?'yxAH',8????????????????'ft':'',9????????????????'ktrqks':?'2020-05-22', 10????????????????'ktrqjs':?'2020-06-22', 11????????????????'spc':'', 12????????????????'yg':'', 13????????????????'bg':'', 14????????????????'ah':'', 15????????????????'pagesnum':?page 16????????????} 17????????????url?=?base_url?+?urlencode(data) 18????????????print(url) 19????????????try: 20????????????????response?=?requests.request("POST",url,?headers?=?headers) 21????????????????#print(response) 22????????????????if?response.status_code?==?200: 23????????????????????re?=?response.content.decode('gbk') 24????????????????????#?print(re) 25????????????????????return?re??#?解析內容 26????????????except?requests.ConnectionError?as?e: 27????????????????print('Error',?e.args)??#?輸出異常信息 28????????except?(TimeoutError,?Exception): 29????????????n?-=?1 30????????????if?n?==?0: 31????????????????print('請求3次均失敗,放棄此url請求,檢查請求條件') 32????????????????return 33????????????else: 34????????????????print('請求失敗,重新請求') 35????????????????continue

構建parse_page函數,對返回的網頁數據進行解析,用Xpath提取所有字段內容,保存為csv格式。有人會問為啥J哥這么喜歡用Xpath,因為簡單好用啊!!!這么簡單的網頁結構搞個正則大法裝x,J哥我做不到啊。

1def?parse_page(html):2????try:3????????parse?=?etree.HTML(html)??#?解析網頁4????????items?=?parse.xpath('//*[@id="report"]/tbody/tr')5????????for?item?in?items[1:]:6????????????item?=?{7????????????????'a':?''.join(item.xpath('./td[1]/font/text()')).strip(),8????????????????'b':?''.join(item.xpath('./td[2]/font/text()')).strip(),9????????????????'c':?''.join(item.xpath('./td[3]/text()')).strip(), 10????????????????'d':?''.join(item.xpath('./td[4]/text()')).strip(), 11????????????????'e':?''.join(item.xpath('./td[5]/text()')).strip(), 12????????????????'f':?''.join(item.xpath('./td[6]/div/text()')).strip(), 13????????????????'g':?''.join(item.xpath('./td[7]/div/text()')).strip(), 14????????????????'h':?''.join(item.xpath('./td[8]/text()')).strip(), 15????????????????'i':?''.join(item.xpath('./td[9]/text()')).strip() 16????????????} 17????????????#print(item) 18????????????try: 19????????????????with?open('./law.csv',?'a',?encoding='utf_8_sig',?newline='')?as?fp: 20????????????????????#?'a'為追加模式(添加) 21????????????????????#?utf_8_sig格式導出csv不亂碼 22????????????????????fieldnames?=?['a',?'b',?'c',?'d',?'e','f','g','h','i'] 23????????????????????writer?=?csv.DictWriter(fp,fieldnames) 24????????????????????writer.writerow(item) 25????????????except?Exception: 26????????????????print(traceback.print_exc())??#代替print?e?來輸出詳細的異常信息 27????except?Exception: 28????????print(traceback.print_exc())

最后,遍歷一下頁數,調用一下函數。OK,搞定!

1????for?page?in?range(1,5):??#這里設置想要爬取的頁數 2????????html?=?get_page(page) 3????????#print(html) 4????????print("第"?+?str(page)?+?"頁提取完成")

我們來看一下最終效果:

Selenium

好學的朋友可能還想看看Selenium是如何來爬AJAX動態加載網頁的,J哥自然會滿足你的好奇心。于是趕緊新建了一個py文件,準備趁勢追擊,用Selenium把這網站爬下來。

首先,把相關庫導進來。

1from?lxml?import?etree 2import?time 3from?selenium?import?webdriver 4from?selenium.?webdriver.support.wait?import?WebDriverWait 5from?selenium.webdriver.support?import?expected_conditions?as?EC 6from?selenium.webdriver.common.by?import?By

然后,用chromedriver驅動打開這個網站。

1def?main(): 2????#?爬取首頁url 3????url?=?"http://www.hshfy.sh.cn/shfy/gweb2017/flws_list.jsp?ajlb=aYWpsYj3D8crCz" 4????#?定義谷歌webdriver 5????driver?=?webdriver.Chrome('./chromedriver') 6????driver.maximize_window()??#?將瀏覽器最大化 7????driver.get(url)

于是,驚喜的發現,報錯了。J哥憑借著六級英語的詞匯儲量,居然看懂了!大概意思是我的驅動和瀏覽器的版本不匹配,只支持79版本的瀏覽器。

J哥很郁悶,因為我以前爬蟲用Selenium沒出現過這種問題啊。J哥不甘心,于是打開了谷歌瀏覽器看了下版本號。

我丟!都更新到81版本啦!既然這樣,那就請好奇的小伙伴等J哥設置好瀏覽器自動更新、重新下載最新驅動后,下次再來聽窩講Selenium爬蟲吧,記得關注此公眾號,精彩不錯過哦~

結 語

總結一下,對于AJAX動態加載網頁爬蟲,一般就兩種方式:解析接口;Selenium。J哥推薦解析接口的方式,如果解析的是json數據,就更好爬了。實在沒轍了再用Selenium吧。

參考鏈接:

Ajax:https://www.w3school.com.cn/php/php_ajax_intro.asp;

Ajax_json:https://www.jianshu.com/p/1897a8068dfb;

Examples:https://www.zhihu.com/question/46528604?sort=created

PS:在公眾號【小詹學Python】后臺回復"law"即可自動獲取本項目完整代碼啦~

由于微信平臺算法改版,公號內容將不再以時間排序展示,如果大家想第一時間看到我們的推送,強烈建議星標我們和給我們多點點【在看】。星標具體步驟為:(1)點擊頁面最上方“小詹學Python”,進入公眾號主頁。 (2)點擊右上角的小點點,在彈出頁面點擊“設為星標”,就可以啦。 感謝支持,比心。

總結

以上是生活随笔為你收集整理的实战|Python轻松实现动态网页爬虫(附详细源码)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。