
1. 虎嗅網文章數據----寫在前面
今天繼續使用pyspider
爬取數據,很不幸,虎嗅資訊網被我選中了,網址為 https://www.huxiu.com/
爬的就是它的資訊頻道,本文章僅供學習交流使用,切勿用作其他用途。
常規操作,分析待爬取的頁面
拖拽頁面到最底部,會發現一個加載更多
按鈕,點擊之后,抓取一下請求,得到如下地址

2. 虎嗅網文章數據----分析請求
查閱該請求的方式和地址,包括參數,如下圖所示

得到以下信息 1. 頁面請求地址為:https://www.huxiu.com/v2_action/article_list 2. 請求方式:POST 3. 請求參數比較重要的是一個叫做page的參數
我們只需要按照上面的內容,把pyspider代碼部分編寫完畢即可。 on_start 函數內部編寫循環事件,注意到有個數字2025
這個數字,是我從剛才那個請求中看到的總頁數。你看到這篇文章的時候,這個數字應該變的更大了。
@every(minutes=24 * 60)def on_start(self):for page in range(1,2025):print("正在爬取第 {} 頁".format(page))self.crawl('https://www.huxiu.com/v2_action/article_list', method="POST",data={"page":page},callback=self.parse_page,validate_cert=False)
頁面生成完畢之后,開始調用parse_page
函數,用來解析 crawl() 方法爬取 URL 成功后返回的 Response 響應。
@config(age=10 * 24 * 60 * 60)def parse_page(self, response):content = response.json["data"]doc = pq(content)lis = doc('.mod-art').items()data = [{'title': item('.msubstr-row2').text(),'url':'https://www.huxiu.com'+ str(item('.msubstr-row2').attr('href')),'name': item('.author-name').text(),'write_time':item('.time').text(),'comment':item('.icon-cmt+ em').text(),'favorites':item('.icon-fvr+ em').text(),'abstract':item('.mob-sub').text()} for item in lis ] return data
最后,定義一個 on_result() 方法,該方法專門用來獲取 return 的結果數據。這里用來接收上面 parse_page() 返回的 data 數據,在該方法可以將數據保存到 MongoDB 中。
# 頁面每次返回的數據 def on_result(self,result):if result:self.save_to_mongo(result) # 存儲到mongo數據庫def save_to_mongo(self,result):df = pd.DataFrame(result) content = json.loads(df.T.to_json()).values()if collection.insert_many(content):print('存儲數據成功')# 暫停1stime.sleep(1)
好的,保存代碼,修改每秒運行次數和并發數

點擊run
將代碼跑起來,不過當跑起來之后,就會發現抓取一個頁面之后程序就停止了, pyspider
以 URL的 MD5 值作為 唯一 ID 編號
,ID 編號相同,就視為同一個任務, 不會再重復爬取。
GET 請求的分頁URL 一般不同,所以 ID 編號會不同,能夠爬取多頁。 POST 請求的URL是相同的,爬取第一頁之后,后面的頁數便不會再爬取。
解決辦法,需要重新寫下 ID 編號的生成方式,在 on_start() 方法前面添加下面代碼即可:
def get_taskid(self,task):return md5string(task['url']+json.dumps(task['fetch'].get('data','')))
基本操作之后,文章入庫
