js 爬虫抓取网页数据( 什么时候用JS数据的网站,解决的方法有各种各样 )
优采云 发布时间: 2021-12-19 13:27js 爬虫抓取网页数据(
什么时候用JS数据的网站,解决的方法有各种各样
)
问题的根源
爬虫不是一劳永逸的写的,因为原站的代码迭代,我们上次写的代码文章已经变成了一堆狗屎。人生不如意,十有八九,这不是阻碍我们学习的绊脚石。我们的出发点是学习,为了让正确的代码具有一定的鲁棒性(robustness),同时也要学习新技术。这次用Selenium来写爬虫的代码,说不定情况会好起来/(ㄒoㄒ)/~~。
什么时候使用请求?
通常我们在抓取网页时,通常期望找到网站的API请求接口,可以通过参数修改来构造API。返回的结果最好是标准的Json格式,也方便我们在Python中做数据持久化。在这种情况下,我们使用 requests 模块无疑是最好的选择,因为这样的代码速度快且质量高。但现实真的很残酷,大多数网站都会通过JS动态填充网页数据,防止爬虫。采取这种措施的网页请求只返回网页的frame,具体数据通过Ajax动态渲染到网页中。Requests 不具备加载和执行 JS 的能力,所以我们无法通过请求的返回来获取真实的数据。
什么时候使用硒?
这个JS填充数据网站有多种解决方案。通常的方法是通过抓包的方式获取JS的接口获取数据。优点前面已经说了,这样写的代码效率更高。缺点也很明显,需要有一定的JS调试基础。因为你找到了一些接口,但是接口传递的参数是JS加密的,需要分析JS找到加密算法,否则就算抓到API也不能用。对于简单的JS,你或许可以在浏览器中调试,但是如果对JS代码进行混淆和压缩,对我们来说简直太多了,这对我们新手来说有点困难。通过Selenium,可以把复杂化繁为简,轻松实现我们需要的功能。
什么是硒?
什么是硒? -引自维基百科
Selenium 是一个 Web 自动化测试框架。他允许用户通过编写代码来操纵浏览器,实现像真实用户一样的浏览器操作行为。对于一些反爬机制严苛的网站,我们可以使用Selenium来操作浏览器,模拟真实用户操作爬取网站数据。这样做的好处是不需要考虑请求发送、cookie、user-agent等一系列需求,只需要编写代码来操作浏览器,通过读取浏览器内容来获取想要的数据。浏览器具有执行JS的能力。网页加载完毕后,读取网页的源代码,就可以得到我们想要的数据了。
接下来,我们通过 Selenium 重写我们之前的爬虫代码。代码稍微简单一些,仅供入门之用。
环境设置
在Python中使用Selenium,需要安装相应的环境。安装环境很简单,大致分为三步:
在虚拟环境的控制台中使用命令:pip install selenium 安装对应的包支持库,并将对应浏览器的路径添加到系统环境变量中。比如我这里使用的是Chrome浏览器,所以需要在Path环境变量中添加Chrome根目录文件夹。这个操作对于开发者来说并不陌生,根据浏览器版本下载相应的驱动。驱动下载地址(点击跳转),注意必须与您浏览器的版本相对应。下载完成后,将文件解压到Python安装目录。
安装完成后,运行以下代码测试是否安装成功。如果安装成功,会运行Chrome打开本站,并在控制台输出网页源码:
from selenium import webdriver
browser = webdriver.Chrome()
browser.get("https://www.weiney.com/")
print(brower.page_sourse)
爬虫分析
抓取网站:http://yoerking.com/static/music_player.html
运行环境:Python 3.6.5
支持库:selenium,requests,beautifulsoup,tqdm
与前面的代码相比,主要的区别在于前面的网页代码是用requests模块完成的。这次我换成了selenium,从浏览器中获取网页的源码。这样省去了分析js的麻烦。但是每次运行爬虫都打开Chrome也会降低软件的效率,但是影响不大,没有请求也会很快。
def get_page_sourse():
browser = webdriver.Chrome()
browser.get(URL)
page_sourse = browser.page_source
browser.close()
return page_sourse
<p>def parse_music():
page_sourse = get_page_sourse()
soup = BeautifulSoup(page_sourse, "html.parser")
all_musics = soup.find_all("a", class_="url")
for music_item in all_musics:
single_music = dict()
single_music["url"] = music_item.attrs["hrefsrc"]
single_music["name"] = music_item.text
single_music["album"] = re.search("(?