今天研究了一下动态网站的抓取,这里用到的时选股宝这个网站:https://xuangubao.cn/
这个小案例是一个简单的抓取选股宝的7x24快讯的资讯内容,并将数据保存到Mysql数据库中。
网页分为静态网页和动态网页,静态网页一般指与后端数据没有交互的网页数据嵌在页面或js里面,动态网页则通过Ajax与数据库交互,可以实时的从数据库获取数据在页面显示。
怎么判断一个网站是动态网站:
1. 在浏览网页时,有些网站可以一直往下翻,边翻边加载数据,这种一般是动态网站。
2. 还可以在浏览器的控制台查看网络中的XHR查看与后台数据交互记录。
首先要找到数据来源,经过观察发现快讯消息是在上图name为newsflash的请求加载的,通过这个请求可以拿到他的url为https://baoerapi.xuangubao.cn/api/v6/message/newsflashlimit=5&cursor=1578327000000&subj_ids=9,10,723,35,469,821&platform=pcweb通过观察这个请求可以发现newsflashlimit参数控制请求返回的记录条数,cursor是毫秒时间戳,因为这里的咨询内容是动态更新的,每隔一段时间就会有新的咨询加载出来,这里是按照时间来排序的,所以只要控制这两个参数就可以获取到想要的咨询内容了。
这里我尝试抓取一个时间段内的咨询内容,时间间隔设置为10分钟。也就是每一次抓取的是10分钟内产生的咨询内容,当然可能会有重复,这里不做处理。
用到的时间戳与时间转换的在线工具:https://tool.lu/timestamp
代码如下
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File : SpiderMan.py
# @Author: Small-orange
# @Date : 2019-1-6
# @Desc :动态网站抓取-选股宝
import requests
from fake_useragent import UserAgent
from sqlalchemy import create_engine
import pandas as pd
import time
#时间:1月7号12:00-17:00
#对应时间戳:1578382200000-1578389400000
#发送请求获取返回数据
def getData(url):
if url is None:
return
ua = UserAgent()
headers = {'User-Agnet':ua.random}
r = requests.get(url,headers=headers)
if r.status_code == 200:
#如果请求返回的是json格式的数据,可以使用json()函数
#也可以使用json.load()函数将json格式的字符串转化成json对象
return r.json()
#提取返回数据中的字段信息
def parserData(data):
#提取数据中的id,title,summary字段的信息
retdata = data.get('data')
msglist = retdata.get('messages')
savelist = []
for msg in msglist:
id = int(msg.get('id'))
title = msg.get('title')
summary = ''
#summary中的字段为空时,将title的值赋给summary
if msg.get('summary') != '':
summary = msg.get('summary').replace('\n','')#去掉摘要中的换行
else:
summary = title
temp = []
temp.append(id)
temp.append(title)
temp.append(summary)
savelist.append(temp)
return savelist
#将数据保存到数据库
def saveData(result_data,con):
#将数据写入数据库中
if len(result_data)>0:
#这里创建DataFrame的时候忘记添加表头,写入数据时一直报错
df = pd.DataFrame(result_data,columns=['id','title','summary'])
# print('df:',df)
# 如果想要自动建表的话把if_exists的值换为replace,建议自己建表,自己建表if_exists的值为append
#name为表名,con为数据库连接
df.to_sql(name="stock_news", con=con, if_exists='append', index=False)
# print('数据保存成功!')
#获取数据库连接
def getContact():
#连接数据库
engine = create_engine('mysql+pymysql://root:123456@localhost:3306/demo01?charset=utf8')
con = engine.connect()
print('Mysql连接创建成功...')
return engine
if __name__ == '__main__':
url = 'https://baoer-api.xuangubao.cn/api/v6/message/newsflash?limit=10&cursor={}&subj_ids=9,10,723,35,469,821&platform=pcweb'
start_time = 1578382200000
con = getContact() #创建数据库连接
count = 0
while True:
#这里设置的时间间隔是10分钟,也就是说每次抓取10分钟之内更新的消息
end_time = start_time + 600000
if end_time>1578389400000:
break
start_time = end_time
now_url = url.format(end_time)
data = getData(now_url)
time.sleep(2) #间隔2秒钟请求一次
result_data = parserData(data)
# print(result_data)
saveData(result_data,con)
count += len(result_data)
print('{}条数据保存成功!'.format(count))
测试的两个小时更新的内容
网友评论