1. 虎嗅網文章數據 寫在前面 今天繼續使用 爬取數據,很不幸,虎嗅資訊網被我選中了,網址為 爬的就是它的資訊頻道,本文章僅供學習交流使用,切勿用作其他用途。 常規操作,分析待爬取的頁面 拖拽頁面到最底部,會發現一個 按鈕,點擊之後,抓取一下請求,得到如下地址 2. 虎嗅網文章數據 分析請求 查閱該 ...
1. 虎嗅網文章數據----寫在前面
今天繼續使用pyspider
爬取數據,很不幸,虎嗅資訊網被我選中了,網址為 https://www.huxiu.com/
爬的就是它的資訊頻道,本文章僅供學習交流使用,切勿用作其他用途。
常規操作,分析待爬取的頁面
拖拽頁面到最底部,會發現一個載入更多
按鈕,點擊之後,抓取一下請求,得到如下地址
2. 虎嗅網文章數據----分析請求
查閱該請求的方式和地址,包括參數,如下圖所示
得到以下信息
- 頁面請求地址為:https://www.huxiu.com/v2_action/article_list
- 請求方式:POST
- 請求參數比較重要的是一個叫做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('存儲數據成功')
# 暫停1s
time.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','')))
基本操作之後,文章入庫