python爬蟲之爬取《貴州農經網》信息

前言:期待已久的科研項目終於有眉目了,這是第一次去找研究生老師做項目,由於時間關係,老師沒能給我安排上任務,叫我和一個研究生學長交接工作。第一個叫我解決的網站就是《貴州農經網》,由於有一個驗證碼,他也不得其解。後來發了一篇秀璋老師寫的文章給我學習,這是秀璋老師在2017年寫的爬蟲,當時的網站還沒有驗證碼,所以會簡單很多,和如今的需求已經不一樣了。

貴州農經網 中國百強農業網站,貴州省優秀政府網站,是貴州省委、省政府爲促進農業增效,促進農民增收而建立的省、地、縣、鄉四級農村綜合經濟信息網。

爬取網站: http://www.gznw.com/eportal/ui?pageId=595091

1、分析網頁

我認爲學習網絡爬蟲的關鍵是分析網頁數據的加載方式,然後再模擬客戶端去請求數據。

1.1、分析數據加載的步驟

1. 先到搜索頁面搜索某個商品,加載信息,如我以線椒爲例:在這裏插入圖片描述
經過測試,只有輸入驗證碼,驗證正確後才能拿到到數據,對於這種必須要驗證碼的網頁,我們可以選擇selenium來爬取,但是我們先再看看其他的方式,如獲取到數據傳輸通道,直接實現查詢功能,這樣的話速度就比selenium快很多!

2. 分析URL
在這裏插入圖片描述
直接點擊“下一頁”,發現URL並沒有什麼變化,還是和以前是一樣的,可以簡單猜想這個數據是通過某種通道加載的,現在來檢驗一下。

3、尋找數據加載通道
這個方式也可以叫做數據抓包,找到這個通道後,就可以直接通過這個通道截取數據。

第一步:右擊–>檢查
在這裏插入圖片描述
第二步:打開Network,選擇All
在這裏插入圖片描述
第三步:輸入驗證碼,點擊查詢加載數據
在這裏插入圖片描述

第四步:尋找數據傳輸通道
從加載出來的結果來看,並不是很多,也便於尋找數據。
我們要尋找的數據是文本型,所以在Type中,直接把目標定在xhr就行了,
在這裏插入圖片描述
這樣我們就找到了需要的數據,目前來看就只有價格和市場名稱可見,添加時間,市場名稱等內容不可見,先看看是否被加密了。

第五步:複製該路徑到瀏覽器中打開試試
在這裏插入圖片描述
第六步:分析結果
在這裏插入圖片描述
從上面的結果來看,其他數據都出來了,就只有中文看不見,全是亂碼的,這樣就可以笑了,因爲數據沒有加密傳輸,只是它們的解碼問題而已~

1.2、請求通道數據

import requests
result = requests.get('http://www.gznw.com/eportal/ui?moduleId=ab59857100d84dcca372ff4473198d88&struts.portlet.mode=view&struts.portlet.action=/portlet/priceFront!queryList.action&pageSize=20&pageNo=1&recruitType=1&categoryDetail=909&marketId=&startDate=2019-11-01&endDate=2020-01-06')
print (result.text)

請求結果:
在這裏插入圖片描述
現在完全可以確定這就是我們需要的數據了,先來把它美化一下吧!

import pprint
pprint.pprint(result.json())

呈現結果:
在這裏插入圖片描述

2、提取數據

2.1、覈對需要爬取的信息

在這裏插入圖片描述

2.2、提取json數據

從上面可以看出這是json數據,可以直接根據目錄查詢到數據

import requests
json = requests.get('http://www.gznw.com/eportal/ui?moduleId=ab59857100d84dcca372ff4473198d88&struts.portlet.mode=view&struts.portlet.action=/portlet/priceFront!queryList.action&pageSize=20&pageNo=3&recruitType=1&categoryDetail=909&marketId=&startDate=2018-01-01&endDate=2019-12-03')
for result in json.json()['result']:
    varietyName = result['varietyName']#商品名稱
    priceType = '批發價' if int(result['priceType']) == 1 else "零售價"#1爲批發價,2爲零售價
    productPrice = result['productPrice']#產品價格
    unit = result['unit']#單位
    marketName = result['marketName']#市場名稱
    createTime = result['createTime'][:10]#[:10]截取出時間中的年月日,去掉具體時分
    print (varietyName,priceType,productPrice,unit,marketName,createTime)

提取結果:

線椒 零售價 6.00/公斤 金沙縣百悅街農貿市場 2019-11-20
線椒 批發價 50.00/公斤 黔西北農產品物流園 2019-11-20
線椒 零售價 12.00/公斤 大方縣新民路菜市場 2019-11-20
線椒 批發價 5.00/公斤 畢節創美農副產品批發交易中心 2019-11-19
線椒 零售價 7.00/公斤 畢節桂花市場 2019-11-19
線椒 零售價 8.00/公斤 赫章縣前河農貿市場 2019-11-19
線椒 零售價 6.00/公斤 鳳岡縣東環路過渡農貿市場 2019-11-19
線椒 批發價 2.60/公斤 雙龍農副產品交易中心 2019-11-18
線椒 零售價 10.00/公斤 盤州農貿市場 2019-11-18
線椒 零售價 4.00/公斤 雷山縣綜合農貿市場 2019-11-16
線椒 批發價 5.00/公斤 黔西北農產品物流園 2019-11-15
線椒 批發價 5.00/公斤 畢節創美農副產品批發交易中心 2019-11-15
線椒 零售價 7.00/公斤 畢節桂花市場 2019-11-15
線椒 零售價 6.00/公斤 金沙縣百悅街農貿市場 2019-11-15
線椒 零售價 20.00/公斤 望謨縣望江新城農貿市場 2019-11-15
線椒 零售價 6.00/公斤 金沙縣百悅街農貿市場 2019-11-14
線椒 批發價 5.00/公斤 黔西北農產品物流園 2019-11-14
線椒 批發價 5.00/公斤 畢節創美農副產品批發交易中心 2019-11-14
線椒 批發價 2.60/公斤 雙龍農副產品交易中心 2019-11-14
線椒 批發價 2.60/公斤 貴陽地利農產品物流園 2019-11-14

2.3、實現翻頁爬取

通過上面說過的分析網頁數據的方法,我們看看第一頁和第二頁的json數據通道有什麼不同,就可以得到我們想要的信息了
在這裏插入圖片描述

2.4、構造json通道

for page in range(1,6,1):
    jsonUrl = "http://www.gznw.com/eportal/ui?moduleId=ab59857100d84dcca372ff4473198d88&struts.portlet.mode=view&struts.portlet.action=/portlet/priceFront!queryList.action&pageSize=20&pageNo={page}&recruitType=1&categoryDetail=909&marketId=&startDate=2019-11-01&endDate=2020-01-06"+str(page)
    print (jsonUrl)

輸出結果:

http://www.gznw.com/eportal/ui?moduleId=ab59857100d84dcca372ff4473198d88&struts.portlet.mode=view&struts.portlet.action=/portlet/priceFront!queryList.action&pageSize=20&pageNo=1&recruitType=1&categoryDetail=909&marketId=&startDate=2019-11-01&endDate=2020-01-061
http://www.gznw.com/eportal/ui?moduleId=ab59857100d84dcca372ff4473198d88&struts.portlet.mode=view&struts.portlet.action=/portlet/priceFront!queryList.action&pageSize=20&pageNo=2&recruitType=1&categoryDetail=909&marketId=&startDate=2019-11-01&endDate=2020-01-062
http://www.gznw.com/eportal/ui?moduleId=ab59857100d84dcca372ff4473198d88&struts.portlet.mode=view&struts.portlet.action=/portlet/priceFront!queryList.action&pageSize=20&pageNo=3&recruitType=1&categoryDetail=909&marketId=&startDate=2019-11-01&endDate=2020-01-063
http://www.gznw.com/eportal/ui?moduleId=ab59857100d84dcca372ff4473198d88&struts.portlet.mode=view&struts.portlet.action=/portlet/priceFront!queryList.action&pageSize=20&pageNo=4&recruitType=1&categoryDetail=909&marketId=&startDate=2019-11-01&endDate=2020-01-064
http://www.gznw.com/eportal/ui?moduleId=ab59857100d84dcca372ff4473198d88&struts.portlet.mode=view&struts.portlet.action=/portlet/priceFront!queryList.action&pageSize=20&pageNo=5&recruitType=1&categoryDetail=909&marketId=&startDate=2019-11-01&endDate=2020-01-065

2.5、寫入csv

3、源碼彙總

import requests,csv,time

startTime =time.time()#獲取開始時的時間
fp = open('G:\\線椒.csv','a',newline='',encoding='utf-8')#創建CSV文件
writer = csv.writer(fp)
writer.writerow(('產品名稱','價格類型','價格','單位','市場名稱','發佈時間')) #csv頭部
for page in range(1,11,1):
    jsonUrl = f"http://www.gznw.com/eportal/ui?moduleId=ab59857100d84dcca372ff4473198d88&struts.portlet.mode=view&struts.portlet.action=/portlet/priceFront!queryList.action&pageSize=20&pageNo={page}&recruitType=1&categoryDetail=909&marketId=&startDate=2019-11-01&endDate=2020-01-06"+str(page)
    json = requests.get(jsonUrl)
    print ("這在爬取第%s個頁面"%page)
    for result in json.json()['result']:
        varietyName = result['varietyName']#商品名稱
        priceType = '批發價' if int(result['priceType']) == 1 else "零售價"#1爲批發價,2爲零售價
        productPrice = result['productPrice']#產品價格
        unit = result['unit']#單位
        marketName = result['marketName']#市場名稱
        createTime = result['createTime'][:10]#[:10]截取出時間中的年月日,去掉具體時分
        position = (varietyName,priceType,productPrice,unit,marketName,createTime)
        writer.writerow((position))#寫入數據    
fp.close() #關閉文件   
endTime =time.time()#獲取結束時的時間
useTime =(endTime-startTime)/60
print ("該次所獲的信息一共使用%s分鐘"%useTime)

編輯器運行截屏:
在這裏插入圖片描述
**提示:**使用數據通道來獲取數據的速度比請求html快n倍,如果沒有其他條件限制的話,強烈推薦使用這個方法!!!

csv結果截屏:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章