背景
用 Python 的 requests 模块爬取金十数据首页中间部分的资讯信息,练习了两种处理过程:写入 MySQL 数据库和词云分析,对比之下 Python 几行代码就能完成 MySQL入库,真是太简洁了!
环境准备
用到的 python 库有:
- PIL
- jieba
- requests
- wordcloud
- pymysql
本机环境为 python 3.6 ,发现有些库如 wordcloud 使用 pip install moduleName 命令安装会失败,不能做到百分百正确安装。找到一个 windows python 库下载地址,可以通过下载 whl 到本地、使用 pip install xxx.whl 进行模块安装。
在该地址上下载模块的安装文件之前,需要确定版本,即根据本机 Python 的版本 + 操作系统的位数确定下载链接。例如,要确定 wordcloud 下载版本,则先在 cmd 下输入 python 命令:
然后选择 Python 3.6 和 window 32 位的下载地址:
爬虫参数分析
用浏览器访问金十数据首页后,点击“加载更多”,分析网络请求的有效数据路径得到这几个:
“加载更多” 点击事件会发送两个相同 URL 的请求,第一个使用方法 Options ,响应码为 204,第二个是有效地址,同时查询参数和请求头域为右侧圈起来的部分。
“加载更多”,这个请求每次是以上一次的最后一条数据的 time 值加上几秒为新一轮查询参数的,它实际就是当前查询到的时间点。编码可以构造一个循环爬虫的过程,在循环体中修正 max_time 参数即可。
爬取数据并入库功能
1.创建一个 MySQL 数据库表
DROP TABLE IF EXISTS `jin10_data`;CREATE TABLE `jin10_data` ( `id` varchar(50) DEFAULT NULL, `time` varchar(20) DEFAULT NULL, `content` longtext) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2.分析响应数据
响应数据是一个 JSON 格式的字符串,真正的数据在 data 属性中,基本 JSON 信息为:
{ "status": 200, "message": "OK", "data": [ { "id": "20190812082759520100", "time": "2019-08-12 08:27:59", "type": 0, "data": { "pic": "", "content": "新西兰财政部:预计资产购买计划是一项效用较低的工具。" }, "important": 0, "tags": [ ], "channel": [ 1 ], "remark": null } ] }
那么需要处理的重要数据就是 response['data'] ,用 type 函数打印它的类型,得知它的类型是 list ,遍历列表、解析每个元素的 id、time 、content 即可。
3.编写爬虫代码
import requestsimport pymysql##定义数据表存储函数def save(conn,cur,id,time,content):sql = '''insert into jin10_data(id,time,content) values(%s,%s,%s);'''try:B = cur.execute(sql,(id,time,content))conn.commit()#print('insert ok')except:print('error')##爬虫获取页面数据url="https://flash-api.jin10.com/get_flash_list"header={ "x-app-id":"SO1EJGmNgCtmpcPF", "x-version":"1.0.0", }queryParam={ "max_time":"2019-08-12 14:18:48", "channel":"-8200",}##创建数据库连接对象conn = pymysql.connect(host='127.0.0.1', user='root', password='123456', db='python_data',charset="utf8")cur = conn.cursor()##循环爬取并插入数据:结束条件是爬不到数据为止totalCount = 0Data=requests.get(url,queryParam,headers=header).json()['data']length = len(Data)while(length>0):for i in range(length) :try:tempTime = Data[i]['time']tempId = Data[i]['id']tempContent = Data[i]['data']['content']save(conn,cur,tempId,tempTime,tempContent)except:print('error')totalCount+=length#修正下一个查询时间queryParam['max_time'] = Data[length-1]['time']print ('next queryParam is',queryParam['max_time'])#再请求一次数据Data=requests.get(url,queryParam,headers=header).json()['data']length = len(Data)### 完成后释放链接cur.close()conn.close()print('all ok,totalCount is:',totalCount)
4.运行结果
运行该脚本,可以一直爬取该网站的数据信息,直到响应数据长度为 0 、结束循环,查询入库结果为:
生成词云
1.准备工作
需要准备字体和词云底图文件,找一个本地字体文件,如宋体 simsun.ttc ,再放一张图片作为词云底图 mask.png。
2.编码
循环爬取 500 条数据后,对 content 信息分词并生产词云图片,完整代码如下:
import jieba.analysefrom PIL import Image,ImageSequenceimport numpy as npimport matplotlib.pyplot as pltfrom wordcloud import WordCloud,ImageColorGenerator##文件内容读取器:用字符串的累加,不能太大,否则应该会有内存问题吧。newsContent= ''import requests##爬虫获取页面数据url="https://flash-api.jin10.com/get_flash_list"header={ "x-app-id":"SO1EJGmNgCtmpcPF", "x-version":"1.0.0", }queryParam={ "max_time":"2019-08-12 14:18:48", "channel":"-8200",}Data=requests.get(url,queryParam,headers=header).json()['data']totalCount = 0length = len(Data)while(totalCount<500):for i in range(length) :try:tempContent = Data[i]['data']['content']newsContent+=tempContentexcept:print('error')totalCount+=length#修正下一个查询时间queryParam['max_time'] = Data[length-1]['time']print ('next params is',queryParam['max_time'])#再请求一次数据Data=requests.get(url,queryParam,headers=header).json()['data']length = len(Data)###关键词分析result=jieba.analyse.textrank(newsContent,topK=50,withWeight=True)keywords = dict()for i in result: keywords[i[0]]=i[1]print(keywords)###生成词云图片image= Image.open('./mask.png')graph = np.array(image)wc = WordCloud(font_path='./simsun.ttc',background_color='White',max_words=50,mask=graph)wc.generate_from_frequencies(keywords)image_color = ImageColorGenerator(graph)plt.imshow(wc)plt.imshow(wc.recolor(color_func=image_color))plt.axis("off")plt.show()wc.to_file('finacial.png')
3.运行结果
运行该脚本,得到一张财经新闻的词云图:
编程启示录
编码过程中的小问题整理:
1)打印一个数据的类型使用 type(data)
2)class list 类型,获取其长度用 len(alist) 方法
3)循环遍历用 for i in range(length)
4)Python 分模块、分文件怎么引用呢?定义在不同文件中,文件名即为模块名,再 import 文件名(不含.py 后缀)调用模块名.function()
5)Python 函数定义必须放在前面,使用在后面,否则会报函数未定义异常。
6)windows 下 Python 库函数安装文件 下载地址 来手动安装,可以解决 pip 自动安装老是出错的问题。
7)数据库操作:三四行代码的事情,比 Java 容易多了。
8)由于每次查询的 max-time 是上次的最后一条记录的时间,所以爬虫两次爬虫会有一条相同记录,这个参数应该稍微调整一下,累加几秒以错开重叠的记录。