Gupiao 数据定向爬虫
Copyright: Jingmin Wei, Pattern Recognition and Intelligent System, School of Artificial and Intelligence, Huazhong University of Science and Technology
文章目录
本教程主要参考中国大学慕课的 Python 网络爬虫与信息提取,为个人学习笔记。
在学习过程中遇到了一些问题,都手动记录并且修改更正,保证所有的代码为有效。且结合其他的博客总结了一些常见问题的解决方式。
本教程不商用,仅为学习参考使用。如需转载,请联系本人。
Reference
由于 Baidu Stock 的网站已经失效,所以这里选择雪球网进行 Stock 的爬虫操作,基本思路还是按照 Baidu 来写。
爬取雪球 Stock 的爬虫实践
基本程序结构设计
算法编写
main 函数
首先我们关注雪球网的 robots 协议,发现其中 User-agent:* 表示禁止信息爬取。所以我们需要访问时以 Mozilla5.0 访问。
因此,当我们使用 requests 库时,爬虫会忠实告诉服务器,这次访问是 python 一个库的程序产生的。雪球网可以让这个访问不支持,所以应该让程序模拟一个浏览器发送爬虫请求。
因此我们需要修改 get 方法的 kv 字段,以 mozilla/5.0 表示标准的浏览器身份标识字段。
def main():
stock_list_url = 'http://21.push2.eastmoney.com/api/qt/clist/get?cb=jQuery11240216110963949796_1586611666127&pn=1&pz=20&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&fid=f3&fs=m:0+t:6,m:0+t:13,m:0+t:80,m:1+t:2,m:1+t:23&fields=f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152&_=1586611666172'
header = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"} #表示标准的浏览器身份标识字段
stock_list = []
get_stock_list(stock_list, stock_list_url, header)
get_stock_info(stock_list, header)
我们设定两个函数,一个用来返回 Stock 列表,一个用来爬取具体的信息并写入文件
get_page 函数
直接利用 requests 的通用代码框架编写即可。
def get_page(url, header):
try:
r = requests.get(url, headers=header)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except Exception as e:
print(e)
get_stock_list 函数
get_page 对应的网站的 html 源码如下图所示,而我们需要获得其中 “f12” 对应的键值对作为 Stock 的代码。经过分析,我们可以明确得知,这是 json 格式的键值对。提取其中的信息并进行检索,可以采用 json.loads 方法,re 与正则表达式。
其函数大致思路为:采用 try - except 的调试错误框架。首先进行 json 格式规范化,删去不必要的符号和字符串,然后利用 json 库中的 loads 方法形成字典,接着进行检索,获得 “f12” 对应的字符串,最后利用正则表达式匹配 “f12” 并将键值对的内容放进列表中。
基本信息组织与提取思路是:
1.提取标准 json 并转为 dict
首先删去标头的 “JQuery…” 和末尾的 “);” 部分形成标准的 json 格式。
stocks2 = page.replace(");", "")
stocks = stocks2.replace("jQuery11240216110963949796_1586611666127(", "")
stocks = json.loads(stocks)
此时我对目前的 json 格式整理如下:
{
"rc":0,
"rt":6,
"svr":182995795,
"lt":1,
"full":1,
"data":{
"total":3969,
"diff":[
{
"f1":2, "f2":57.76, "f3":20.01, ...... "f12":"688365", "f13":1, "f14":"光云科技",......
},
{
"f1":2, "f2":100.0, "f3":10.85, ...... "f12":"688039","f13":1,"f14":"当虹科技",......
},
......
{
"f1":2, "f2":14.27, "f3":10.02, ...... "f12":"300203","f13":0,"f14":"聚光科技",......
}
]
}
}
可以看到,当 json 格式通过 json.loads 转为字典形式,便形成了四维的字典,而我们需要的信息在 diff 的键值对下,因此,我们需要提取 [“data”][“diff”] ,以获取我们的信息,并进一步进行处理。
stocks = stocks["data"]["diff"]
提取完毕后,程序成功返回了二维的字典。
2.转为 string
获取了 diff 键值对的字典后后,我们转为 string 格式,并删去不必要的字符 “[”, “]”, “{” , “,” ,最后,根据 “}” 对字符串进行切片。
stocks = stocks["data"]["diff"]
stocks = str(stocks)
stocks = stocks.replace("[", "")
stocks = stocks.replace