python学习笔记分享(三十六)网络爬虫(3)静态网页与动态网页简单爬取之selenium环境的搭建
IT Xiao Ang Zai 2019年3月24号
版本:python3.7
编程软件:Pycharm,Sublime Text 3
当我们浏览网络上的很多网站时,就会发现,有些网站的网页中的数据都呈现在网页的HTML代码中,有些却不在。那些所有数据都呈现在网页上HTML代码的网页,如果要爬取其中的数据,是很容易的;而其他一些用Ajax动态加载网页的数据不一定会出现在HTML代码中,爬取它们会有困难。下面就分别介绍爬取这两种不同网页的爬虫技术。
一:静态网页爬取
1.静态网页说明:静态网页就是不会有用户和服务器进行数据交换的网页,所有的数据都显示在HTML页面。
2.静态网页主要技术:urllib,Requests库,定制请求头模拟浏览器访问。
3.爬取步骤
(1)这里用到的是Requests库,我们用语句pip install requests就可以安装了。
(2)爬取网页基础信息
先用如下语句获取网页response响应对象:
import requests
rr = requests.get("url地址")
然后我们可以从这个对象中选出我们需要的信息:
rr.text:服务器响应的内容,如果在头部指定了编码,会自动进行解码。
rr.encoding:服务器内容的文本编码。
rr.status_code:状态码,前面有提到。
rr.content:字节码的响应体,会自动解码gzip和deflate编码的响应数据。
rr.json():内置的JSON解码器,会自动解码json数据。
(3)前面已经提到了,有时候浏览器不欢迎爬虫程序的爬取,会屏蔽我们的程序,这时候我们可以通过修改User-agent,延迟提交数据,使用代理等方法进行隐藏。这里就不介绍了。
(4)有时候我们为了请求特定的数据,尤其是批量请求数据时,会通过url地址的规律进行爬取,一般是通过寻找一些键值对来发现规律。还有就是会发送一些表单数据进行POST,返回特定的数据,需要我们把传给服务器的数据先构成一个字典,传给requests中的data参数,前面是传给urllib.request模块的urlopen中的data参数,效果是一样的,这些数据字典就会在发出请求时自动编码为表单形式。
(5)有时候服务器会长时间没有响应,我们需要自己进行关闭程序的操作,但有时候我们不知道程序什么时候关闭合适,有时还会造成程序崩溃,因此我们需要设置一个timeout参数,如果在timeout秒内没有响应,就返回异常。
二:动态网页爬取
1.动态网页说明:有时候,我们需要的数据在HTML代码中没有,是用JavaScript进行加载的,爬取静态网页的技术根本达不到我们的要求,需要我们进行更高级的技术爬取动态网页。
2.动态网页主要技术:通过浏览器审查元素解析真实网页地址和使用selenium模拟浏览器。
3.爬取步骤:
(1)首先我们需要了解网页上一种异步更新技术-Ajax,在前面的jQuery的讲解中已经提到,大家可以参看该文章https://blog.****.net/ITxiaoangzai/article/details/85053852。
(2)但是由于Ajax比较方便,且十分迅速,是很高级的技术,因此爬取用Ajax加载的数据是很麻烦的。但还是有技术可以克服。我们试着爬取百度问答上的回答,地址如下:https://zhidao.baidu.com/question/1994726764151738147.html?fr=qlquick&is_expand_answer=1&entry=list_default_level2。
(3)我们首先查看一下网页源代码,发现回答并没有加载到HTML页面上。
(4)解析真实地址爬取
但是我们还是可以找到数据的真实地址。
先右键打开"检查"功能:
然后单击页面中的Network选项,这时候我们看到还是为空的:
我们刷新一下网页,此时会显示浏览器从服务器中得到的所有文件,这个过程称为"抓包"。里面是所有的文件,我们需要的文件一定在里面。
(5)这些数据一般是json文件格式,我们可以单击Network中的XHR选项,找到真正的问答,然后改变我们的地址即可。
(6)如果返回的是json格式,则需要导入json模块进行解析,这里简单介绍:
json.load()是加载json格式字符串,变为json数据,json.dump()是把json数据进行解析,变为字符串。
4.通过selenium模拟浏览器抓取
(1)原因:有时候,通过检查功能,很难找到调用的网页地址。而且,有一些真实数据的网页地址十分冗长和复杂,有些网站还会对地址进行加密。
(2)为了解决这些问题,我们可以用浏览器渲染引擎,直接自动操作浏览器,把爬取动态网页变成静态网页。
这里有一个python的selenium库可以模拟浏览器进行抓取。
(3)简介:
selenium是一个用于Web应用程序测试的工具,支持的浏览器包括IE(7, 8, 9, 10, 11),Firefox,Safari,Google Chrome,Opera等。包含了测试的录制(selenium IDE),编写及运行(Selenium Remote Control)和测试的并行处理(Selenium Grid)。
(3)安装selenium:
安装它与安装模块一样,直接用pip进行安装:
pip install selenium
安装后如下,提示已经安装成功了:
我们使用的是谷歌浏览器,大家还需下载一个Chromedriver文件,然后把它放在python的安装目录下。
其他浏览器对应不同的文件,火狐浏览器对应geckdriver,ie对应IEdriver。
这时候,我们在Pycharm运行,结果还会出现错误:
这里的原因就可能是python的路径问题了,我们在命令行输入python,然后输入from selenium import webdriver,回车后是否报错,没报错则说明成功安装selenium包。
然后我们打开设置,然后选择Show All:
点击框框中的+号,在点击System Interpeter选项,从右边的Interpreter把你安装的python路径加进去即可:
在project Interpeter那里选择你加入的python路径,如出现pip、selenium、setuptools模块则代表成功了,可以使用selenium了:
当然,用sublime是不会出现这个问题的。
(4)打开谷歌浏览器
用一下代码就可以打开谷歌浏览器了。
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.2345.com/baidu/baidusearch.html')
(5)使用方法
由于selenium使用了浏览器渲染,因此那些评论数据已经渲染到了HTML代码中。可以用"检查"的方法定位元素位置。
代码如下:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://zhidao.baidu.com/question/1994726764151738147.html?fr=qlquick&is_expand_answer=1&entry=list_default_level2')
comment = driver.find_element_by_css_selector('div#answer-content-3020813995')
print(comment.text)
结果如下:
下面就介绍selenium选择元素的常用方法:
find_element_by_css_selector | 通过元素的class选择 |
find_element_by_xpath | 通过xpath选择 |
find_element_by_id | 通过元素的id选择 |
find_element_by_name | 通过元素的name选择 |
find_element_by_link_text | 通过链接地址选择 |
find_element_by_partial_link_text | 通过链接的部分地址选择 |
find_element_by_tag_name | 通过元素的名称选择 |
find_element_by_class_name | 通过元素的class选择 |
在上面的选择方法中把elemet后加上s,就可以查找多个元素。
还有一些selenium操作元素的方法:
clear | 清除元素的内容 |
send_keys | 模拟按键输入 |
click | 单击元素 |
submit | 提交表单 |
这里我们先在我们的页面上进行操作,网页代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>我的页面</title>
</head>
<body>
<div align="center" style="margin: 100px 0px 100px 0px">
<form>
<table border="1" cellpadding="0" bordercolor="#9DCFFF">
<tr>
<td bgcolor="#E7FBFF" align="right">名字:</td>
<td><input type="text" name="username" value="" maxlength="20" size="20" /></td>
</tr>
<tr>
<td bgcolor="#E7FBFF" align="right">姓名:</td>
<td><input type="text" name="xingming" value="" maxlength="10" size="20" /></td>
</tr>
<tr>
<td bgcolor="#E7FBFF" align="right">登录名:</td>
<td align="left">
<input type="text" value="" name="denglu" maxlength="10" size="20" /><font>(可包括a-z,0-9和下划线)</font></td>
</tr>
<tr>
<td bgcolor="#E7FBFF" align="right">密码:</td>
<td><input type="password" name="userpsd" size="20" maxlength="15"><font>(至少包含6个字符)</font></td>
</tr>
<tr>
<td bgcolor="#E7FBFF" align="right">再次输入密码:</td>
<td><input type="password" name="userpsd" size="20" maxlength="15" /></td>
</tr>
<tr>
<td bgcolor="#E7FBFF" align="right">电子邮箱:</td>
<td><input type="text" name="email" size="20" maxlength="20" /><font>(必须包含@字符)</font></td>
</tr>
<tr>
<td bgcolor="#E7FBFF" align="right">性别:</td>
<td><input type="radio" name="sex" value="男" checked="checked" id="man"/>男<input type="radio" name="sex" value="女" id="woman">女</td>
</tr>
<tr>
<td bgcolor="#E7FBFF" align="right">出生日期:</td>
<td><input type="text" name="year" size="3" maxlength="4" value="yyyy">年
<select>
<option value="">[请选择月份]</option>
<option value="1月" id="first">1月</option>
<option value="2月" id="second">2月</option>
<option value="3月" id="third">3月</option>
<option value="4月" id="four">4月</option>
<option value="5月" id="five">5月</option>
<option value="6月" id="six">6月</option>
<option value="7月" id="seven">7月</option>
<option value="8月" id="eight">8月</option>
<option value="9月" id="nine">9月</option>
<option value="10月" id="ten">10月</option>
<option value="11月" id="eleven">11月</option>
<option value="12月" id="twelve">12月</option>
</select>
月<input type="text" size="3" maxlength="2" name="ri" value="dd">
日</td>
</tr>
<tr>
<td bgcolor="#E7FBFF" align="right"><input type="reset" value=" 重写 " name="no"></td>
<td><input type="submit" value="同意提交" name="yes" size="30"></td>
</tr>
<tr>
<td colspan="2">
<b>阅读下面协议</b>
<br>
<br>
<br>
</td>
</tr>
<tr>
<td colspan="2">
<textarea cols="100px" rows="5px">
这里是协议
</textarea>
<br>
<br>
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
python代码如下:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('E:\\python\\wangluopachong\\myd\\my.html')
username = driver.find_element_by_name("username")
username.clear
username.send_keys("IT Xiao Ang Zai")
xingming = driver.find_element_by_name("xingming")
xingming.clear
xingming.send_keys("李大")
denglu = driver.find_element_by_name("denglu")
denglu.clear
denglu.send_keys("123456")
userpsd = driver.find_element_by_name("userpsd")
userpsd.clear
userpsd.send_keys("*********")
email = driver.find_element_by_name("email")
email.clear
email.send_keys("[email protected]")
driver.find_element_by_id("woman").click()
chuSheng = driver.find_element_by_name("year")
chuSheng.clear
chuSheng.send_keys("2019")
driver.find_element_by_id("three").click()
ri = driver.find_element_by_name("ri")
ri.clear
ri.send_keys("24")
driver.find_element_by_name("yes").click()
我们看一下结果:
是不是感觉运行速度很快,而且最后的结果还没有显示。在之后会向大家介绍如何控制加载速度以及暂停页面。
有关动态加载网页的简单知识就介绍到这里,欢迎大家继续跟着我的笔记进行学习,还希望大家积极指出我的错误,互相进步。