最近在實習,同事給我安排了個小任務:寫一個爬蟲把雪球網上關注度比較高的股票抓下來,每天2點抓一次,然後同時將股票信息通過釘釘推送給他。
我像往常一樣用requests抓取頁面,但是我發現這樣得到的結果和在瀏覽器中看到的不一樣,我找不到我需要的內容。在瀏覽器中可以看到正常顯示的頁面數據,但是使用requests得到的結果並沒有。
經過百度發現是因爲,requests獲取的都是原始的HTML文檔,而瀏覽器中的頁面則是經過JavaScript處理數據後生成的結果,這些數據的來源有多種,可能是通過Ajax加載的,可能是包含在HTML文檔中的,也可能是經過JavaScript和特定算法計算後生成的。
所以如果遇到這樣的情況,就要用其他的辦法。
1. 請求
進入網頁:https://xueqiu.com/
打開Ajax的XHR過濾器,然後在熱股榜裏一直點“滬深”,“港股或”美股”,就可以看到,會不斷有Ajax請求發出。
也就是不斷的會有“list.josn?size=8&&_type=....”出現。
選定我們關注的“滬深”。點擊該請求,進入詳情頁面。
可以發現,這是一個GET類型的請求,請求鏈接爲:
https://stock.xueqiu.com/v5/stock/hot_stock/list.json?size=8&_type=12&type=12
請求的參數有3個: size, _type和type
2. 響應
點開Preview觀察響應內容:
展開其中一個,可以看到更詳細的信息。
3. 實現
# -*-coding:utf-8-*-
from urllib.parse import urlencode
from pyquery import PyQuery as pq
import requests
from bs4 import BeautifulSoup as bs
import os
headers = {
'Host': 'stock.xueqiu.com',
'Referer': 'https://xueqiu.com/',
'X-Application-Context': 'xueqiu-stock-api-rpc:production',
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36',
}
base_url = 'https://stock.xueqiu.com/v5/stock/hot_stock/list.json?'
def get_stock_list():
params = {
'size': 8,
'_type': 12,
'type': 12
}
url = base_url + urlencode(params)
try:
res = requests.get(url, headers=headers)
if res.status_code == 200:
return res.json()
except requests.ConnectionError as e:
print('Error', e.args)
def parse_info(json):
if json:
items = json.get('data').get('items')
for i in items:
info = {}
info['code'] = i.get('code')
info['name'] = i.get('name')
info['value'] = i.get('value')
yield info
json = get_stock_list()
results = parse_info(json)
for result in results:
print(result)
很遺憾, requests的結果是status_code爲400。但是網頁卻是能夠正確響應。
我查了很多博客都沒能解決這個問題,最後我把打開這個網頁的Cookie加到headers中,發現就可以返回正常結果了。
但是linux下的pycharm無法顯示中文,所以顯示有點問題。
但結果是正確的啦!