您的位置:首页 > Web前端 > JavaScript

新世界!打开Selenium和PhantomJs的大门!--爬虫福音

2017-03-02 12:51 609 查看

前言

写过爬虫的朋友一定知道我们遇到的梦魇是什么,对,没错,就是动态网页!什么是动态网页?给没有了解过的朋友普及一下,就是网页最后的内容不是一开始就是完整的,而是等代码都加载完毕之后再执行一段js代码来补充网页的内容。比如说网页最后的内容是A,最初的代码是B,B里面包含一段js代码,这段代码执行之后可以产生C,这样B+c才等于A。而我们通过网络访问网页的url得到的只是B。这样做确实在很大程度上防止了一些简单爬虫的访问。像我就比较喜欢看漫画,所以就想写一个漫画爬虫,而漫画网站一般都是使用动态技术,后台要么使用AJAX技术,要么就是js来加密图片地址,反正一般爬虫途径是拿不到漫画图片的地址的。

这里就以乐神漫画网为例,我们先来看漫画的浏览页面:



这是一页内容,那么怎么拿到这张图片呢?这里我使用Python的爬虫框架BeautifulSoup得到的内容是这样的:



这个就是得到的img标签的内容,这里是没有图片的地址的。因为这里使用了onload属性,这里就是动态执行js代码然后改变src的值也就是我们的图片地址。除非我们能执行那一段js代码,否则就很难拿到地址。对,除非我们能执行那一段js代码,接下来就是本文的重点。

如何执行这一段js代码呢?js代码是依赖于浏览器的,所以找一个浏览器。那么就有人要问了,如果用浏览器还能叫爬虫吗?因为程序自动执行所以才方便的,如果自己手动操作那么还说什么呢。那么我就要说了,谁说我要手动操作了,浏览器难道不能是用代码执行的吗?如果有一个用代码执行控制的浏览器,那么浏览器就会执行那段js代码,这样我们通过浏览器就可以得到最后网页的内容也就是包括漫画图片地址。

说了这么多,那么这个浏览器是什么呢?它就是PhantomJs,你可以把它想象成一个没有界面的浏览器,它可以执行访问网页,执行js代码,得到的网页内容都可以通过代码得到。不过必须通过另一个框架来操作,也就是Selenium,这个框架是用来做测试的。不过这里我使用它来做爬虫。

本文使用的语言是Python,所以selenium是Python的一个框架,当然其他语言也有相应的框架,但是我没有去试。笔者的系统是ubuntu,windows的用户可以根据过程进行参考。

环境搭建

Selenium安装

pip install selenium


如果安装失败那么加上
sudo
权限。

PhantomJs安装

大家可以去官网下载,也可以在网上搜索。下载完毕之后解压即可。我把它放在了
/usr/local/mysoft/phantomjs-2.1.1


代码实现

首先需要导入selenium

from selenium import webdriver


拿到了webdriver之后就得到一个浏览器对象

url = "http://www.dangniao.com/mh/22996/392953.html"
browser = webdriver.PhantomJS("/usr/local/mysoft/phantomjs-2.1.1/bin/phantomjs")
browser.get(url)


传入PhantomJs的路径就可以了,然后通过get方法访问url就可以得到网页的内容,因为是一个浏览器,所以会执行js代码,所以得到的内容是最终完整的页面内容。

接下来就是怎么得到图片地址。

首先通过Chrome浏览器的开发者工具得到img标签的位置



可以看到是由一个id为“wdwailian”的div包裹着img,所以可以通过下面的方法

[1]
src = browser.find_element_by_css_selector("#wdwailian img").get_attribute("src") //通过CSS来选择,如果是id则加"#",如果是class则加"."

[2]
div = browser.find_element_by_id("wdwailian")
img = div.find_element_by_tag_name('img')
src = img.get_attribute('src')




可以看到,我们已经可以得到图片的地址了。

这样还不是PhantomJs最强的功能,最强的是可以模拟用户的点击。现在我们只是得到了一张图片,那么第二张图片怎么办呢?

再来看一下网页



这里有下一页按钮,我们点击下一页就可以跳到第二页内容,自然也可以得到下一张图片地址。那么该怎么做呢?

首先需要下一页在网页中的位置



可以看到这是一个”a”标签,通过class我们就可以得到这个a标签对象,代码如下:

browser.find_element_by_class_name("zsxiaye").click() # 模拟用户点击
src = browser.find_element_by_css_selector("#wdwailian img").get_attribute("src")


这样就可以得到下一页的内容,那么我想下载这一话所有的内容,那么来几个循环即可,执行结果如下:



完整代码:

# -*- coding:utf-8 -*-
from selenium import webdriver

if __name__ == '__main__':
url = "http://www.dangniao.com/mh/22996/392953.html" browser = webdriver.PhantomJS("/usr/local/mysoft/phantomjs-2.1.1/bin/phantomjs") browser.get(url)
for i in range(24):
div = browser.find_element_by_id("wdwailian")
img = div.find_element_by_tag_name('img')
src = img.get_attribute('src')
print src
if i!=23: #如果不是最后一页就点击下一页
browser.find_element_by_class_name("zsxiaye").click() # 模拟用户点击


这只是一话的内容,如果想得到所有话的内容并下载那么可以参考我下面的程序,下载结果如下:





完整代码:http://download.csdn.net/detail/programchangesworld/9768167
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: