抓取jsp网页源代码(Ajax动态分析待抓取的微博内容:准备工作:安装好requests库)
优采云 发布时间: 2021-11-03 02:14抓取jsp网页源代码(Ajax动态分析待抓取的微博内容:准备工作:安装好requests库)
Ajax动态分析待抓取微博内容:准备:安装requests库和lxml库
输入cmd
pip install requests
pip install lxml
因为我之前安装过这两个库,所以这里安装的时候会显示下图的内容:
分析网页
打开Chrome浏览器,我们输入这个网站:。右击选择查看网页源代码。这时候我们会发现,我们在首页看到的文字内容,在网页的源代码中并没有显示出来。这意味着网页是由 Ajax 动态加载的。(下图左边是我能看到的网页,右边是网页的源代码)
我们在右边随机选择一段内容,在左边搜索,没有任何结果。在这里,我们以“人间烟火,香饽饽”来寻找栗子:
我们看到我们搜索的内容并没有出现在源码中,所以网页是通过Ajax动态加载的。
Ajax,全称是Asynchronous JavaScript and XML,即异步JavaScript和XML。它不是一种编程语言,而是一种使用 JavaScript 与服务器交换数据并更新部分网页的技术,同时保证页面不会被刷新,页面链接不会发生变化。
对于传统的网页,如果要更新其内容,必须刷新整个页面,而使用Ajax,您可以在不完全刷新页面的情况下更新其内容。在这个过程中,页面实际上是在后台与服务器进行数据交互。获取到数据后,通过JavaScript来改变网页,从而更新网页的内容。
你可以在W3School上体验几个例子来感受一下:。
其实很多网页都是这样的。我们将继续向下滑动网页,并会不断刷新和加载我们眼前的新内容。
既然我们已经知道它是用 Ajax 动态加载的,那么我们来分析一下它是如何交换数据的。
右击选择Check(或按键盘F12)进入开发者模式。网页的样式展现在我们眼前。
在Elements中,我们可以看到网页的源码,右边是节点的内容,但这不是我们想要的。如果我们按照常规的网页请求,提取网页标签中的数据,就得不到我们想要的内容。.
我们进入Network,在Network下选择XHR,我们会看到如下内容(第一次进入,没有该内容,刷新页面即可):
随着我们继续滚动鼠标滚轮,XHR下加载的内容越来越多,我们会在getIndex的开头看到一个请求,点击查看其详细信息
我们看到Request Headers里面有个参数是X-Requested-With:XMLHttpRequest。通过这个参数,我们可以更加确定它是由Ajax动态加载的。然后点击Headers旁边的Preview,里面的数据是json(类似于python字典的字符串)格式。
点击卡片,卡片下有10条内容,我们到下面9条内容中的mblog一一查看,会发现微博正文中收录的文字收录在raw_text中
(其实这个请求中也收录了图片,想要下载图片的游客可以自行研究图片链接)。现在我们已经找到了我们想要的东西,让我们开始编写错误,“抓住”这些词并将它们放入我们的“口袋”中。
请求数据
我们使用requests.get(url)来请求网页,因为我们要请求的网页不是开头给出的网页,而是我们分析后发现的Ajax网页请求。所以我们真正要求的应该是这个网页%3D1%26q%3D%E6%80%9D%E6%83%B3%E8%81%9A%E7%84%A6&type=uid&value=1742566624&containerid=66624,打开这个页面我们你会发现里面有密密麻麻的字符和数字。我们可以在浏览器中找到一个json数据在线解析网址。这个还好。将上面网页的内容复制到json网页,我们就可以看到整齐的json数据了。很像python中的字典格式。
在 jupyter 中写这个:
response = requests.get('https://m.weibo.cn/api/container/getIndex?uid=1742566624&t=0&luicode=10000011&lfid=100103type%3D1%26q%3D%E6%80%9D%E6%83%B3%E8%81%9A%E7%84%A6&type=uid&value=1742566624&containerid=1076031742566624')
if response.status_code == 200:
html = response.json()
我们直接将其转成json格式,在jupyter中打印出来,随时查看网页返回的信息是什么样子的。(爬虫、数据分析等推荐使用jupyter,方便随时查看结果)
运行上面的代码并得到以下输出:
不难发现,这个数据和我们在Preview中看到的数据是一样的,说明我们得到的就是我们想要的数据。接下来,我们需要从这个字典中提取微博文本的内容。NS。代码显示如下:
get_details = html.get('data').get('cards')
for i in range(len(get_details)):
text = get_details[i].get('mblog').get('raw_text').strip()
print(text)
操作结果如下:
由于cards是一个列表,收录十条数据,我们使用for循环遍历整个列表并提取数据。因为我们返回的数据是字典类型的,所以我们可以直接使用get来提取数据。或者根据键值对索引(推荐get,如果当前没有key,索引会报错,get返回空值,不会阻止程序失败)。这样,我们从“第一页”中提取了十条数据,但是这样的数据量往往不能满足我们的需求。
获取多页数据
如果我们把每个网页都复制粘贴到我们的脚本中,10个可能的问题都不算大。首先找到getIndex,然后将网页复制粘贴到脚本中。一共三个步骤,10个网页是30个步骤。但是 100 页呢?这时候处理起来就比较麻烦了。所以我们需要找到一个“好方法”来构建网页,让脚本本身去“查找网页”→“复制”→“粘贴”“查找网页”\rightarrow“复制”\rightarrow“粘贴”“查找网页” “→”复制”→“粘贴”,一般我们可以把这种重复的工作交给程序来完成。所以我们现在要做的就是“教”我们的爬虫脚本来做到这一点。
回顾我们请求的页面: %3D1%26q%3D%E6%80%9D%E6%83%B3%E8%81%9A%E7%84%A6&type=uid&value=1742566624&containerid=66624 这是我们的第一页请求,让我们看看我们要请求的第二个页面看起来像: %3D1%26q%3D%E6%80%9D%E6%83%B3%E8%81%9A%E7 %84%A6&type=uid&value= 1742566624&containerid=66624&since_id=45596。第二个网页似乎与第一个网页不同。它比第一个网页有一个小尾巴 since_id。其实我们再看第三、第四、第五……从第二个开始的网页,它们都有一个since_id的参数,所以我们只需要在后面的每个网页上加上一个since_id的参数第一个网页的基础。但是好像每个网页对应的since_id都不一样,所以如果要调侃的话,它似乎不起作用。但是,它的网页毕竟是人写的,不是上帝创造的,所以它的since_id肯定是我们聪明的小脑袋“创造”出来的。
由于这个网页的since_id要被浏览器捕获,不断请求下一页的数据,我们自己找出这个since_id并不难。
果然,我们可以在json数据的cardlistInfo中找到一个since_id的key
让我们将这个since_id 与下一个网页中的since_id 进行比较。这是相同的。(我这里截取的是首页的since_id,这个since_id也会随着时间的推移而变化,访问者看到的和我的不一样,正常),我们使用get获取since_id就像提取文本信息一样。既然找到了这个since_id的构造规则,就可以请求多页网页数据了。只要我们教我们的爬虫脚本如何使用我们为它找到的since_id来构建网页,它就可以不断地获取网页。内容也是。
构建网页的代码如下:
def group_url(since_id):
params = {
'since_id':since_id
}
url = base_url + '&' + urlencode(params)
return url
urlencode是urllib.parse中的方法,下面是官方文档:
函数中传入的since_id就是我们为爬虫找到的since_id。然后我们把构造好的网页返回给网页请求函数,解析提取我们想要的内容和sinance_id,这样我们就可以一直循环下去了。
存储数据
编写爬虫不应该只是为了爬取数据,如果我们下次要使用这些数据,再次爬取,那会很麻烦,所以我们“隐藏”了我们从网上“偷”出来的东西。起来。这里我们使用记事本来保存这些文本数据(当然也可以写入数据库,有兴趣的读者可以自行上网搜索写入数据库的操作)。保存数据的代码如下:
def write_title():
title = '思想聚焦的微博正文'
with open('blog.txt','w',encoding = 'utf-8') as f:
f.write(title + '\n')
f.write('\n')
def write_infos(txt):
with open('blog.txt','a',newline='\n',encoding = 'utf-8') as f:
f.write(txt)
f.write('\n')
因为我们这里抓取的是思维聚焦微博文章,标题写的是“思维聚焦微博正文”,然后每一行都留空(这样看起来更整洁)。参数 newline 这就是它的作用。
至此,我们的爬虫已经写完了。有兴趣的话,可以做词云图,做情感分析等等……
完整代码:
import requests
import json, time
from lxml import etree
from urllib.parse import urlencode
base_url = """https://m.weibo.cn/api/container/getIndex?uid=1742566624&t=0&luicode=10000011
&lfid=100103type%3D1%26q%3D%E6%80%9D%E6%83%B3%E8%81%9A%E7%84%A6&type=uid&value=1742566624&containerid=1076031742566624"""
HEADERS = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36",
"X-Requested-With":"XMLHttpRequest",
"Referer":"https://m.weibo.cn/u/1742566624"
}
def write_title(): # 写入标题
title = '思想聚焦的微博正文'
with open('blog.txt','w',encoding = 'utf-8') as f:
f.write(title + '\n')
f.write('\n')
def write_infos(txt): # 写入正文
with open('blog.txt','a',newline='\n',encoding = 'utf-8') as f:
f.write(txt)
f.write('\n')
def group_url(since_id): # 构造网页的函数
params = {
'since_id':since_id
}
url = base_url + '&' + urlencode(params)
return url
def get_html(url): # 请求网页
response = requests.get(url,headers=HEADERS)
if response.status_code == 200:
return response.json()
def get_infos(html): # 提取信息
since_id = html.get('data').get('cardlistInfo').get('since_id')
get_details = html.get('data').get('cards')
for i in range(len(get_details)):
text = get_details[i].get('mblog').get('raw_text').strip()
print(text)
write_infos(text)
return group_url(since_id)
def main():
write_title()
first_page = get_html(base_url)
new_url = get_infos(first_page)
for i in range(5): # 我这里以提取5页数据为栗子
html = get_html(new_url)
new_url = get_infos(html)
main()
在这个脚本中,我们设置了请求头,让我们的爬虫看起来更像是浏览器正在访问。
操作结果:
总结:
当我们查看网页的源代码时,我们发现在网页上看到的源代码中没有任何信息。对于Ajax网页的抓取,我们应该分析它的动态加载包,而不是直接请求它的源代码。通过构造Ajax网页URL来实现对多页信息的抓取,不同的网站其构造url的方法是不同的。为此,您需要自己查找规则并构建 url。看完这篇文章,如果你觉得可以爬取Ajax网页,可以尝试爬取今日头条上面的内容,也是Ajax加载的。
提取网页信息的方法有很多种,但在这种情况下,我们恰好是字典的形式。如果遇到其他情况,就得行动起来,用最熟悉的信息抽取方式抓取网页信息。让我们停在这里。它有点简陋,但可以大致看到。