背景
用 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 requests
import 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 = 0
Data=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.analyse
from PIL import Image,ImageSequence
import numpy as np
import matplotlib.pyplot as plt
from 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 = 0
length = len(Data)
while(totalCount<500):
for i in range(length) :
try:
tempContent = Data[i]['data']['content']
newsContent+=tempContent
except:
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
是上次的最后一条记录的时间,所以爬虫两次爬虫会有一条相同记录,这个参数应该稍微调整一下,累加几秒以错开重叠的记录。