生活随笔
收集整理的這篇文章主要介紹了
局部页面切换url为什么不变_python爬虫 - 翻页url不变网页的爬虫探究
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
python爬蟲(chóng)-翻頁(yè)url不變網(wǎng)頁(yè)的爬蟲(chóng)探究
url隨著翻頁(yè)改變的爬蟲(chóng)已經(jīng)有非常多教程啦,這里主要記錄一下我對(duì)翻頁(yè)url不變網(wǎng)頁(yè)的探究過(guò)程。學(xué)術(shù)菜雞第一次寫(xiě)CSDN,請(qǐng)大家多多包容~ 如果對(duì)你有一點(diǎn)點(diǎn)幫助,請(qǐng)幫我點(diǎn)個(gè)贊吧!
翻頁(yè)url不變 與 翻頁(yè)url改變 有什么區(qū)別?
url其實(shí)就是鏈接,翻頁(yè)url改變的鏈接就是翻頁(yè)請(qǐng)求在url中體現(xiàn)的鏈接,比方說(shuō)很多爬蟲(chóng)初學(xué)者的第一個(gè)爬蟲(chóng)實(shí)例:爬取豆瓣電影top250的信息。
注意看這個(gè)網(wǎng)站的鏈接!!
這里可以看到控制頁(yè)數(shù)的參數(shù)start直接在url中體現(xiàn)了,改變start=之后的數(shù)值就能夠?qū)崿F(xiàn)翻頁(yè)。start=25對(duì)應(yīng)的頁(yè)面就是從26開(kāi)始的電影,start=0對(duì)應(yīng)的頁(yè)面就是從1開(kāi)始的電影。那么只需要控制start之后的數(shù)字以25為步長(zhǎng)遞增就可以通過(guò)for函數(shù)實(shí)現(xiàn)翻頁(yè)。
但是有時(shí)候會(huì)遇到明明你點(diǎn)擊了翻頁(yè),但url卻不改變的情況,比如這個(gè):
這種情況沒(méi)有辦法在python中直接通過(guò)改變url實(shí)現(xiàn)翻頁(yè)。
找到翻頁(yè)命令
事實(shí)上,控制網(wǎng)頁(yè)翻頁(yè)總得有一個(gè)參數(shù),只是在翻頁(yè)url改變的情況中,這個(gè)翻頁(yè)參數(shù)體現(xiàn)在了url中,這使得我們可以通過(guò)直接改變url的方式實(shí)現(xiàn)翻頁(yè)。對(duì)于翻頁(yè)url不變的情況,我們其實(shí)只需要找到翻頁(yè)命令所在的位置,然后控制這條命令即可。
下面介紹我找到翻頁(yè)命令的一種方式:
打開(kāi)開(kāi)發(fā)者模式在打開(kāi)開(kāi)發(fā)者模式的情況下點(diǎn)擊翻頁(yè)找到翻頁(yè)后返回的內(nèi)容表單 (一般是XHR格式)查看其headers (注意pages,start,p等字眼)提取相應(yīng)的部分,在python中編寫(xiě)語(yǔ)句實(shí)現(xiàn)控制就可以控制翻頁(yè)了爬取去哪兒酒店信息實(shí)例
- 打開(kāi)開(kāi)發(fā)者模式,并點(diǎn)擊翻頁(yè)
- 找到返回的第二頁(yè)內(nèi)容的表單可以點(diǎn)擊list-preview打開(kāi)表單預(yù)覽,確認(rèn)這個(gè)list確實(shí)是服務(wù)器返回的第二頁(yè)酒店內(nèi)容這里可以看到list里面的內(nèi)容確實(shí)就是第二頁(yè)的酒店內(nèi)容,那么我們就要尋找這個(gè)list是怎么返回的,即它是通過(guò)向服務(wù)器發(fā)送什么命令返回的!!
- 查看list的headers
可以發(fā)現(xiàn)在Request Headers之下多了一個(gè)新的模塊,叫做Request Payload(我之前在CSDN上看到很多帖子,都是講From Data或者Query String Parameters,但是我卻一直沒(méi)找到這兩個(gè)模塊,只有Request Payload,后來(lái)經(jīng)過(guò)高人指點(diǎn)才知道,其實(shí)在Request Payload內(nèi)也有可能隱藏著翻頁(yè)的信息,所以我在想不一定要局限在具體的模塊名字,關(guān)鍵是找到翻頁(yè)之后服務(wù)器返回的信息表單,找它的headers有什么與第一頁(yè)headers不同的地方)
- 將Request Payload的內(nèi)容打開(kāi)觀察
觀察Request Payload里的內(nèi)容,發(fā)現(xiàn)這條指令其實(shí)是向服務(wù)器發(fā)送了一些要求,比如說(shuō)要求了需要查找的酒店所在城市是西安,還指定了查詢(xún)的日期。可以看到這里有一條start:20的命令,經(jīng)過(guò)對(duì)比第一頁(yè)list的同一位置(start:0)發(fā)現(xiàn)start:i就是控制返回不同頁(yè)面的命令。
至此我們已經(jīng)發(fā)掘到了翻頁(yè)url不變網(wǎng)站的翻頁(yè)命令,下面只需要在爬蟲(chóng)構(gòu)造headers的時(shí)候,加上Request Payload里要求的內(nèi)容,其中start控制內(nèi)容由函數(shù)參數(shù)控制。這樣就實(shí)現(xiàn)了控制爬取頁(yè)數(shù)的操作。除此之外,不難發(fā)現(xiàn)我們甚至還可以控制通過(guò)控制Request Payload中的city方便地實(shí)現(xiàn)對(duì)不同城市酒店的爬取。
代碼
下面附上完整代碼,由于去哪兒網(wǎng)頁(yè)時(shí)常加載失敗,所以如果前兩次出現(xiàn)“No targets found”很有可能是由于鏈接網(wǎng)頁(yè)失敗,多試幾次就好了。
- 通過(guò)修改main()里的city,可以爬取不同城市的酒店信息。
- 通過(guò)修改getlist()里z的范圍,可以改變爬取頁(yè)數(shù)。
- 我沒(méi)有對(duì)正則提取的內(nèi)容做任何模糊處理,理論上復(fù)制這個(gè)代碼就可以運(yùn)行。
- 大多數(shù)城市直接輸入城市拼音就可以爬到(鏈接失敗就多試幾次),但是北京得用beijing_city。如果有的城市試了很多次都鏈接失敗,可以上去哪兒網(wǎng)手動(dòng)搜索看看url里的city是怎樣的,手動(dòng)添加一下就可以了。
#-*- codeing = utf-8 -*-#@Time : 2020/8/4 9:25 上午#@Author : Tango#@File : hotel_general.py#@Software : PyCharmimport timeimport reimport requestsfrom bs4 import BeautifulSoupimport xlwtimport jsonfindname = re.compile(r'(.*?)')findgrade = re.compile(r'
(3|4|("4)).(.*?)')findtotal = re.compile(r'共(.*)條評(píng)論')findprice = re.compile(r'¥(.*)起')finddetail = re.compile(r'查看詳情')def askurl(city, i, url): #獲取網(wǎng)頁(yè)內(nèi)容(post) request_payload = { "b": "{bizVersion: "17", cityUrl:" + city + ", cityName: "", fromDate: "2020-08-04", toDate: "2020-08-05", q: "",…}", "bizVersion": "17", "channelId": 1, "cityName": "", "cityType": 1, "cityUrl": city, "comprehensiveFilter": [], "fromAction": "", "fromDate": "2020-08-04", "fromForLog": 1, "hourlyRoom": "false", "level": "", "locationAreaFilter": [], "maxPrice": -1, "minPrice": 0, "num": 20, "q": "", "qFrom": 3, "searchType": 0, "sort": 0, "start": int(i*20), "toDate": "2020-08-05", "userId": "", "userName": "", "uuid": "", "qrt": "h_hlist", "source": "website" } head = { "user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36" } response = requests.post(url, headers=head, data=json.dumps(request_payload)) #headers里表示這里的數(shù)據(jù)獲取是post方法,所以使用requests.post函數(shù) return response.textdef getlist(city, url): hotellist = [] for z in range(0, 3): # 爬取頁(yè)數(shù)設(shè)置 page = askurl(city, z, url) #爬取第z頁(yè) soup = BeautifulSoup(page, 'html.parser') #是一個(gè)樹(shù)形結(jié)構(gòu)了 lsts = soup.find_all('div', class_="inner clearfix" ) ##表空判斷 if not lsts: print("No targets found") print("連接到網(wǎng)頁(yè)失敗") exit(0) print("鏈接網(wǎng)頁(yè)成功,開(kāi)始爬取數(shù)據(jù)") number = 1 #非空情況下讀取 for item in lsts: hotel = [] #每個(gè)hotel存放一個(gè)酒店的信息(列表形式) item = str(item) # 酒店名稱(chēng) hotel_name = re.findall(findname, item)[0] hotel.append(hotel_name) # 酒店評(píng)分 hotel_grade = re.findall(findgrade, item) temp = list(hotel_grade) if temp: hotel.append(temp[0][0]) hotel.append(temp[0][2]) else: hotel.append(0) hotel.append(0) # 酒店總評(píng)分?jǐn)?shù) hotel_total = re.findall(findtotal, item)[0] hotel.append(hotel_total) # 酒店起步價(jià) hotel_price = re.findall(findprice, item) if len(hotel_price): hotel_price = hotel_price[0] else: hotel_price = 0 hotel.append(hotel_price) # 詳情鏈接 hotel_info = re.findall(finddetail, item)[0] hotel.append(hotel_info) # 寫(xiě)入hotellist hotellist.append(hotel) print("-----正在爬取第%d條酒店信息-----"%number) number += 1 time.sleep(1.5) time.sleep(7.5) print("第%d頁(yè)爬取完成"%(z+1)) return hotellistdef listToExcel(city, list): col = ['酒店名稱(chēng)', '酒店評(píng)分整數(shù)', '酒店評(píng)分小數(shù)', '酒店評(píng)價(jià)總數(shù)', '起步價(jià)', '詳情網(wǎng)址'] hotelbook = xlwt.Workbook(encoding = "utf-8", style_compression = 0) hotelsheet = hotelbook.add_sheet("sheet1", cell_overwrite_ok = True) for i in range(len(col)): hotelsheet.write(0, i, col[i]) for i in range(0,len(list)): print("-----正在寫(xiě)入第%d條酒店信息-----"%(i+1)) item = list[i] for j in range(len(col)): hotelsheet.write(i+1, j, item[j]) hotelbook.save(city + "hotel.xls")def main(): city = "beijing_city" #基本上寫(xiě)入城市拼音即可,但是北京要寫(xiě)成beijing_city baseurl = "https://hotel.qunar.com/city/" + city + "/#fromDate=2020-01-01&cityurl=xiamen&toDate=2020-01-02&from=qunarHotel" hotellist = getlist(city, baseurl) listToExcel(city, hotellist) #askurl(baseurl)if __name__ == '__main__': main()學(xué)會(huì)了么 學(xué)會(huì)了就私信小編 01 領(lǐng)取驚喜哦
總結(jié)
以上是生活随笔為你收集整理的局部页面切换url为什么不变_python爬虫 - 翻页url不变网页的爬虫探究的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。