python爬虫爬取异步加载网页信息(python抓取网页中无法通过网页标签属性抓取的内容)

1.问题描述

最近由于学习内容的要求,需要从网页上抓取一些数据来做分析报告,在看了python爬虫的一些基础知识之后就直接上手去网站上爬数据了。作为新手踩坑是无法避免,最近就遇到了一个比较难的问题:
一般情况下,要抓去网页上某个标签上的内容,在通过urllib下载网页内容后通过BeautifulSoup对象解析网页内容,然后就可以通过fina_all()方法找到我们想要的标签内容。
举个例子,我想抓取QQ音乐分类歌单下的所有歌单信息,将任务分解后应该是:

  1. 抓取当前页面的歌单信息;
  2. 翻页;
  3. 判断是否是最后一页,若不是最后一页回到第1步,若是最后一页,结束爬虫程序。

首先写一个简单的抓取单页面所有歌单的标题的代码:

import urllib
from bs4 import BeautifulSoup

url = https://y.qq.com/portal/playlist.html
html = urllib.urlopen(url)
bsObj = BeautifulSoup(html)
playTitle_list = bsObj.find_all("span", {"class": "playlist__title_txt"})	# 抓取该页面歌单标题并保存在列表中
print(playTitle_list)
for playTitle in playTitle_list:	# 输出所有标题
	print(i.get_text())

标签参数通过右击网页检查网页属性可以找到歌单标题信息通过属性class 取值为 playlist_title_txt 的span标签展示,但是在执行代码后输出结果只有一个空列表,很奇怪是不是?作为一个新手我是真的是花了好长时间绞尽脑汁都想不出原因。

之后和同学交流听他聊到他之前看到的异步加载内容,发现和我抓取的网页特征有点像,就特地去了解了一下

通俗的描述一下就是这个异步加载的网页所展示的内容并全是来自当前的网址所代表的网页文件,其中有一部分内容是当前的网页文件通过函数调用另一个网页的内容加载过来的,也就是说要抓取的内容所属的网页文件和当前网页文件确实不是同一个文件,所以抓取不到。因此需要找到抓取的内容真正所属的文件。

2.解决方案

接下介绍如何寻找异步加载的文件以及抓取过程中可能会遇到的坑
1.右击网页选择**“检查”,在调试界面中找到“网络”(network)选项,然后逐个找js文件(记得刷新网页不然js文件不会显示出来),通过preview**来查看内容是不是自己想爬去的内容
在这里插入图片描述

2.在每个js文件的具体信息面板中可以通过preview来查看传递过来的内容,我们找到了歌单标题信息的源文件,然后通过Headers属性可以找到给信息真正的源文件的链接,并将url作为我们的requests参数。
在这里插入图片描述

在Headers属性下的general 和request headers包括了我们要的信息,其中url在general属性下,同时也包括了传值类型,这里的是get。
因此我们可以通过request模块获取歌单信息。这里需要注意的是:要把网页的request headers值传递给requests模块的get方法,不然无法获取网页

import requests
url = ...
headers ={...} # headers信息要以字典的形式保存
jsContent = requests.get(url).text

3.以上处理过程一般情况下获得的是json对象(看起来是字典的字符串表现形式),在python中可以直接使用json模块,将json对象转换成python对象—字典,以方便通过key来获取数据

jsDict = json.loads(jsContent)

但是有时候获取的数据形式会在json对象外加上json对象名称,比如:

playList({...}) # 其中{}表示json对象内容

这样的话就无法通过 json模块转换数据类型,一般会出现异常

json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

这个异常情况可以通过字符串的切片把json对象信息截取出来,之后就可以通过json模块转换数据类型了(这是我想出的一个比较笨方法,如果有大佬知道比较正规的方法,希望指正一下 (っ•̀ω•́)っ✎⁾⁾ )

猜你喜欢

转载自blog.csdn.net/braveheartm/article/details/84194764