抓取动态网页(块标签,打开后里面没有网页数据(XHR-1))
优采云 发布时间: 2022-01-15 04:13抓取动态网页(块标签,打开后里面没有网页数据(XHR-1))
块标签,打开后没有网页数据
点击网络选项卡,我们可以看到网页向服务器发送了很多请求,数据很多,查找时间太长了
我们点击XHR分类,可以减少很多不必要的文件,节省很多时间。
【XHR类型是通过XMLHttpRequest方法发送的请求,可以在后台与服务器进行数据交换,也就是说可以在不加载整个网页的情况下更新网页某一部分的内容。也就是说,请求数据库然后得到响应的数据是XHR类型的]
然后我们开始在XHR类型下一一搜索,发现如下数据
查看请求的标头并获取其 url
url=",10,723,35,469,821&limit=30"
在 Firefox 的新窗口中打开此地址
打开后我们可以看到上面的情况,这是一个json格式的文件。然后,它的数据信息以字典的形式存储,数据存储在“NewMsgs”的键值中。
所以,我们可以通过访问["NewMsgs"]的键值来获取网页数据
然后我们查看我们需要的“好”和“坏”对应的key-value,以及时事通讯推荐的股票和行业对应的key-value。
通过查看字典,我们可以很快发现推荐股票是一个嵌套字典,即字典加列表加字典。对应的key值是["NewMsgs"][i]['Stocks'] 同理,对应的推荐行业key值是:["NewMsgs"][i]['BkjInfoArr']
通过对比网页数据,我们可以找到对应的“好”和“坏”时事通讯。
通过对比,我们发现带有好评的时事通讯的“影响”值为1,而“影响”的值为“0”,带有负面标签的短信的值为“-1”。
知道数据的位置后,我们开始编写代码。
先爬取网页,伪装成火狐浏览器,添加header访问数据库地址,防止被识别和拦截。
def get_page(url):
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36'
}
req = urllib.request.Request(url=url,headers=headers)
res = urllib.request.urlopen(req)
html = res.read().decode()
return html
从上面的分析可以知道,数据是以json的形式存储的,所以上面的网页爬取返回的html就是json格式的数据。所以我们需要格式化json。
json.dumps()#把python对象转化成json格式对象
json.loads()#把json格式转化成python对象
转换后,我们可以通过以下字典的键值输出“好”、“坏”、推荐“股票”、推荐“行业”
行业:html["NewMsgs"][i]['BkjInfoArr']
时间:html["NewMsgs"][i]['UpdatedAt']
股票:html["NewMsgs"][i]['Stocks'][j]['Name']
利好:html["NewMsgs"][i]['Impact'] Impact = -1 --->利空 Impact = 1 --->利好
所以获取数据的代码是:
def get_data(html,url):
html = json.loads(html)
c = len(html["NewMsgs"])
for i in range(0,c):
cun =html["NewMsgs"][i]['Impact']#获取含有信息的字典
if cun == 1 or cun == -1:#判断信息是利好还是利空
print(html["NewMsgs"][i]['UpdatedAt'])
if cun == 1:
print("*************利好*************")
if cun == -1:
print('*************利空*************')
chang = len(html["NewMsgs"][i]['BkjInfoArr'])#获取信息下含有几个利好或利空行业
ch =html["NewMsgs"][i]['Stocks']
for j in range(0,chang):
print('行业:',html["NewMsgs"][i]['BkjInfoArr'][j]['Name'])
if ch!=None:
du = len(html["NewMsgs"][i]['Stocks'])#同理获取含有几个利好或利空股票
for k in range(0,du):
print('股票:',html["NewMsgs"][i]['Stocks'][k]['Name'])
print("**************************\n\n")#信息获取完毕,换行
return 0
通过运行发现获取到的数据非常少,只能获取到“点击加载更多”上显示的内容,无法获取到点击加载后的数据。
我们的爬虫爬不了这么少的数据,我们需要的是一个能爬取数据的爬虫,包括点击“加载更多”按钮后的数据。否则最好直接使用爬虫直接访问网站。那么我们如何才能将它与以下数据一起捕获呢?
我们再次输入review元素的XHR类型,通过点击“Load more”按钮,找到加载后保存有新内容的文件,然后再次review元素。
我们找到了保存新数据的文件和新文件的url地址
我们注意到url发生了变化,点击打开链接“,10,723,35,469,821&limit=30&tailmark=1529497523&msgIdMark=310241”
后面的字符比前面的数据 url 多一些。让我们多点击几次“Load More”,查看新内容的文件数据,看看能不能找到一些规律。
让我们将新的网址放在一起进行比较:
https://api.xuangubao.cn/api/pc/msgs?subjids=9,10,723,35,469,821&limit=30&tailmark=1529497523&msgIdMark=310241
https://api.xuangubao.cn/api/pc/msgs?subjids=9,10,723,35,469,821&limit=30&tailmark=1529493624&msgIdMark=310193
https://api.xuangubao.cn/api/pc/msgs?subjids=9,10,723,35,469,821&limit=30&tailmark=1529487816&msgIdMark=310151
第一个网址:
第二个网址:
第三个网址:
通过对比我们可以发现,加载的json数据文件的地址与之前的json文件的['TailMark']和['TailMsgId']有关。
它是在原来的url=",10,723,35,469,821&limit=30"的基础上,加上一个后缀
“&tailmark=['TailMark']&msgIdMark=['TailMsgId']”
并获取 url 地址。
所以,我们获取下一个 url 地址的代码是:
def get_newurl(html):
url="https://api.xuangubao.cn/api/pc/msgs?subjids=9,10,723,35,469,821&limit=30"
url=url+'&tailmark='+html['TailMark']+'&msgIdMark='+html['TailMsgId']
return url
那么我们的爬虫代码就基本完成了。以下是整个爬虫的代码:
# -*- coding:utf-8 -*-
import urllib.request
import urllib.parse
import time
import json
#获取网页
def get_page(url):
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36'
}
req = urllib.request.Request(url=url,headers=headers)
res = urllib.request.urlopen(req)
html = res.read().decode()
return html
#获取下一页网址
def get_newurl(html):
url="https://api.xuangubao.cn/api/pc/msgs?subjids=9,10,723,35,469,821&limit=30"
url=url+'&tailmark='+html['TailMark']+'&msgIdMark='+html['TailMsgId']
return url
#获取数据
def get_data(html,url):
html = json.loads(html)
c = len(html["NewMsgs"])
for i in range(0,c):
cun =html["NewMsgs"][i]['Impact']#获取含有信息的字典
if cun == 1 or cun == -1:#判断信息是利好还是利空
print(html["NewMsgs"][i]['UpdatedAt'])
if cun == 1:
print("*************利好*************")
if cun == -1:
print('*************利空*************')
chang = len(html["NewMsgs"][i]['BkjInfoArr'])#获取信息下含有几个利好或利空行业
ch =html["NewMsgs"][i]['Stocks']
for j in range(0,chang):
print('行业:',html["NewMsgs"][i]['BkjInfoArr'][j]['Name'])
if ch!=None:
du = len(html["NewMsgs"][i]['Stocks'])#同理获取含有几个利好或利空股票
for k in range(0,du):
print('股票:',html["NewMsgs"][i]['Stocks'][k]['Name'])
print("**************************\n\n")#信息获取完毕,换行
#获取通过函数获取下一页的url地址并返回该地址
url = get_newurl(html)
return url
if __name__=='__main__':
url="https://api.xuangubao.cn/api/pc/msgs?subjids=9,10,723,35,469,821&limit=30"
for i in range(0,5):#进行循环爬取下一页地址的股票信息
html=get_page(url)
url=get_data(html,url)
因为刚开始学习,所以很多地方都没有写好,比较繁琐和乏味。也求大神赐教。