动态网页抓取(什么是动态网页爬取的响应信息?寻找我们想要的结果 )

优采云 发布时间: 2021-12-10 06:05

  动态网页抓取(什么是动态网页爬取的响应信息?寻找我们想要的结果

)

  上一篇文章简单介绍了静态网页的爬取,今天给大家分享一些动态网页爬取的技巧。什么是动态网页?举个很常见的例子,当我们在浏览网站的时候,随着我们不断向下滑动网页,当前页面会不断刷新新的内容,但是浏览器地址栏上的URL却一直没有改变。这种由JavaScript动态生成的页面,当我们通过浏览器查看其网页源代码时,往往找不到页面显示的内容。

  抓取动态页面有两种常用的方法。一是通过JavaScript逆向获取动态数据接口(真实访问路径),二是使用selenium库模拟真实浏览器获取JavaScript渲染的内容。但是selenium库使用起来比较麻烦,爬取速度也比较慢,所以日常用的比较多的是第一种方法。

  在做JS反向转发之前,首先要学会使用浏览器抓包。以Chrome浏览器为例打开网易新闻首页

  

  右键查看网页源代码与按F12打开开发者工具看到的源代码不同,当我们下拉页面时,开发者工具中的源代码还在不断增加。这是JS渲染后的源码。也是当前网站显示内容的源码。

  

  如上图所示,Network选项卡主要用于抓包的时候。按F5刷新页面后,下方显示框中会出现很多包。我们可以使用上面的过滤器栏对这些包进行分类。

  

  这里主要使用XHR和JS两种。比如选择XHR,点击过滤后的第一个包。显示界面如下,右侧会出现一排选项卡。Headers 收录当前包的请求消息头和响应消息头。; Preview是响应消息的预览,Response是服务器响应的代码。

  

  了解了这些之后,我们依次点击XHR和JS下的所有包,通过Preview预览当前包的响应信息,找到我们想要的结果。比如我们在下面的包中找到了文章列表,通过Headers找到了Request URL。这是我们真正应该请求的路径。

  

  

  滚动页面的时候发现JS下添加了如下包和新的Request URL。与之前的相比,很容易找到一个通用的URL。分析完这个,我们就可以开始写代码了。

  

  直接编码

  import requests

from bs4 import BeautifulSoup

import json

import re

import multiprocessing

import xlwt

import time

def netease_spider(headers, news_class, i):

if i == 1:

url = "https://temp.163.com/special/00804KVA/cm_{0}.js?callback=data_callback".format(news_class)

else:

url = 'https://temp.163.com/special/00804KVA/cm_{0}_0{1}.js?callback=data_callback'.format(news_class, str(i))

pages = []

try:

response = requests.get(url, headers=headers).text

except:

print("当前主页面爬取失败")

return

start = response.index('[')

end = response.index('])') + 1

data = json.loads(response[start:end])

try:

for item in data:

title = item['title']

docurl = item['docurl']

label = item['label']

source = item['source']

doc = requests.get(docurl, headers=headers).text

soup = BeautifulSoup(doc, 'lxml')

news = soup.find_all('div', class_='post_body')[0].text

news = re.sub('\s+', '', news).strip()

pages.append([title, label, source, news])

time.sleep(3)

except:

print("当前详情页面爬取失败")

pass

return pages

def run(news_class, nums):

headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.63 Safari/537.36'}

tmp_result = []

for i in range(1, nums + 1):

tmp = netease_spider(headers, news_class, i)

if tmp:

tmp_result.append(tmp)

return tmp_result

if __name__ == '__main__':

book = xlwt.Workbook(encoding='utf-8')

sheet = book.add_sheet('网易新闻数据')

sheet.write(0, 0, '文章标题')

sheet.write(0, 1, '文章标签')

sheet.write(0, 2, '文章来源')

sheet.write(0, 3, '文章内容')

news_calsses = {'guonei', 'guoji'}

nums = 3

index = 1

pool = multiprocessing.Pool(30)

for news_class in news_calsses:

result = pool.apply_async(run, (news_class, nums))

for pages in result.get():

for page in pages:

if page:

title, label, source, news = page

sheet.write(index, 0, title)

sheet.write(index, 1, label)

sheet.write(index, 2, source)

sheet.write(index, 3, news)

index += 1

pool.close()

pool.join()

print("共爬取{0}篇新闻".format(index))

book.save(u"网易新闻爬虫结果.xls")

  这里我们抓取了国内和国际版块,在每个版块方向滚动了所有文章 3次,通过文章详情页上的链接爬取了文章的内容,最后爬上了到 289 文章。

  

  需要注意的是,过快的抓取频率会导致访问失败。建议每次都睡一会。此外,增加个人测试中的线程数也很有用。如果可能,您可以添加一个 ip 代理池。我以前用过免费ip。基本上可以使用的ip很少,所以还是要付费的。所有代码和数据已经上传到github,链接在GitHub

  本文与微信公众号“NLP炼金术士”同步,感兴趣的同学可以扫码关注,获取更多内容。

  

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线