浅谈python爬虫使用Selenium模拟浏览器行为


Posted in Python onFebruary 23, 2018

前几天有位微信读者问我一个爬虫的问题,就是在爬去百度贴吧首页的热门动态下面的图片的时候,爬取的图片总是爬取不完整,比首页看到的少。原因他也大概分析了下,就是后面的图片是动态加载的。他的问题就是这部分动态加载的图片该怎么爬取到。

分析

他的代码比较简单,主要有以下的步骤:使用BeautifulSoup库,打开百度贴吧的首页地址,再解析得到id为new_list标签底下的img标签,最后将img标签的图片保存下来。

headers = {
 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'
}

data=requests.get("https://tieba.baidu.com/index.html",headers=headers)
html=BeautifulSoup(data.text,'lxml')

前面提到过,有部分图片是动态加载的,那么首先我们得弄清楚,这部分图片是怎么动态加载的。在浏览器中打开百度贴吧的首页,可以明显的看到,在往下滚动滚动条的时候,当滚动到底部的时候,滚动条缩短了,并向上移动了一段距离。这个现象也正是有DOM元素动态的添加到了html文档的一个表现。动态加载数据无非就是ajax请求,而ajax本质上就是XMLHttpRequest请求(简称xhr)。在谷歌浏览器中,我们可以通过开发者工具的network面板来监测xhr请求。

刚打开首页时的xhr请求,这里的请求都和要爬取的图片无关。

浅谈python爬虫使用Selenium模拟浏览器行为

滚动条向下第1次滚动到底部,这里请求的是第20-40条热门动态,包含要爬取图片。

浅谈python爬虫使用Selenium模拟浏览器行为

滚动条向下第2次滚动到底部,这里请求的是第40-60条热门动态,包含要爬取图片。并且返回的的has_more:false表明没有跟多数据了。

浅谈python爬虫使用Selenium模拟浏览器行为

滚动条向下第3次滚动到底部,再无xhr请求。

解决方案

根据上面的分析,我们已经明白,单纯使用BeautifulSoup进行爬虫的时候,只能爬取到1-20条热门动态里面的图片。为了爬取到完整的热门动态里面的图片,我们则需要模拟浏览器的滚动条滚动,让网页去触发xhr请求更多的热门动态。

在python中,如果需要模拟浏览器的行为,可以使用selenium库。selenium库是一个自动化测试框架,可以用来模拟测试浏览器的各种行为,这里我们使用它来模拟浏览器打开百度贴吧的首页,并模拟滚动条向下滚动到底部的操作。

安装

pip install selenium

下载浏览器驱动

火狐浏览器驱动,其下载地址是:https://github.com/mozilla/geckodriver/releases

谷歌浏览器驱动,其下载地址是:http://chromedriver.storage.googleapis.com/index.html?path=2.33/

opera浏览器驱动,其下载地址是:https://github.com/operasoftware/operachromiumdriver/releases

对照自己电脑安装的浏览器和对应的版本,分别从上面的地址下载驱动文件,也可以从我的github项目中统一下载以上几个驱动(地址:https://github.com/Sesshoumaru/attachments/tree/master/Selenium%20WebDriver)。下载解压后,将所在的目录添加系统的环境变量中。当然你也可以将下载下来的驱动放到python安装目录的lib目录中,因为它本身已经存在于环境变量(我就是这么干的)。

浅谈python爬虫使用Selenium模拟浏览器行为

使用python代码模拟浏览器行为

要使用selenium先需要定义一个具体browser对象,这里就定义的时候就看你电脑安装的具体浏览器和安装的哪个浏览器的驱动。这里以火狐浏览器为例:

from selenium import webdriver
browser = webdriver.Firefox()

再模拟打开贴吧首页:

browser.get(https://tieba.baidu.com/index.html)

再模拟滚动条滚动到底部

for i in range(1, 5):
 browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
 time.sleep(1)

最后再使用BeautifulSoup,解析图片标签:

html = BeautifulSoup(browser.page_source, "lxml")
imgs = html.select("#new_list li img")

几个注意点

必须安装浏览器和浏览器驱动,并且浏览器和浏览器驱动要配到

即如果使用谷歌浏览器模拟网页行为,则需要下载谷歌浏览器驱动;
如果使用火狐浏览器模拟网页行为,则需要下载火狐浏览器驱动

浏览器驱动所在的目录要在环境变量中,或者定义浏览器browser的时候指定驱动的路径

selenium更多用法

查找元素

from selenium import webdriver

browser = webdriver.Firefox()
browser.get("https://tieba.baidu.com/index.html")

new_list = browser.find_element_by_id('new_list')
user_name = browser.find_element_by_name ('user_name')
active = browser.find_element_by_class_name ('active')
p = browser.find_element_by_tag_name ('p')

# find_element_by_name 通过name查找单个元素
# find_element_by_xpath 通过xpath查找单个元素
# find_element_by_link_text 通过链接查找单个元素
# find_element_by_partial_link_text 通过部分链接查找单个元素
# find_element_by_tag_name 通过标签名称查找单个元素
# find_element_by_class_name 通过类名查找单个元素
# find_element_by_css_selector 通过css选择武器查找单个元素
# find_elements_by_name 通过name查找多个元素
# find_elements_by_xpath 通过xpath查找多个元素
# find_elements_by_link_text 通过链接查找多个元素
# find_elements_by_partial_link_text 通过部分链接查找多个元素
# find_elements_by_tag_name 通过标签名称查找多个元素
# find_elements_by_class_name 通过类名查找多个元素
# find_elements_by_css_selector 通过css选择武器查找多个元素

获取元素信息

btn_more = browser.find_element_by_id('btn_more')
print(btn_more.get_attribute('class')) # 获取属性
print(btn_more.get_attribute('href')) # 获取属性
print(btn_more.text) # 获取文本值

元素交互操作

btn_more = browser.find_element_by_id('btn_more')
btn_more.click() # 模拟点击,可以模拟点击加载更多

input_search = browser.find_element(By.ID,'q')
input_search.clear() # 清空输入

执行JavaScript

# 执行JavaScript脚本
browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
browser.execute_script('alert("To Bottom")')

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
使用Python的Supervisor进行进程监控以及自动启动
May 29 Python
Python3基础之基本运算符概述
Aug 13 Python
详解Python中expandtabs()方法的使用
May 18 Python
Python 闭包的使用方法
Sep 07 Python
Python异常的检测和处理方法
Oct 26 Python
python matplotlib imshow热图坐标替换/映射实例
Mar 14 Python
python3 正则表达式基础廖雪峰
Mar 25 Python
python实现坦克大战
Apr 24 Python
Python包和模块的分发详细介绍
Jun 19 Python
python中scipy.stats产生随机数实例讲解
Feb 19 Python
python Autopep8实现按PEP8风格自动排版Python代码
Mar 02 Python
pytorch中Schedule与warmup_steps的用法说明
May 24 Python
python kmeans聚类简单介绍和实现代码
Feb 23 #Python
python MysqlDb模块安装及其使用详解
Feb 23 #Python
Python实现k-means算法
Feb 23 #Python
python语言中with as的用法使用详解
Feb 23 #Python
python实现定时自动备份文件到其他主机的实例代码
Feb 23 #Python
Python机器学习算法之k均值聚类(k-means)
Feb 23 #Python
python3调用R的示例代码
Feb 23 #Python
You might like
PHP循环语句笔记(foreach,list)
2011/11/29 PHP
解析关于java,php以及html的所有文件编码与乱码的处理方法汇总
2013/06/24 PHP
php将12小时制转换成24小时制的方法
2015/03/31 PHP
Laravel5.5 实现后台管理登录的方法(自定义用户表登录)
2019/09/30 PHP
用于table内容排序
2006/07/21 Javascript
Javascript document.referrer判断访客来源网址
2020/05/15 Javascript
浅析javascript闭包 实例分析
2010/12/25 Javascript
JavaScript中双叹号!!作用示例介绍
2014/09/21 Javascript
get(0).tagName获得作用标签示例代码
2014/10/08 Javascript
一个检测表单数据的JavaScript实例
2014/10/31 Javascript
JS实现支持多选的遍历下拉列表代码
2015/08/20 Javascript
jQuery点击按钮弹出遮罩层且内容居中特效
2015/12/14 Javascript
每日十条JavaScript经验技巧(一)
2016/06/23 Javascript
javascript实现右下角广告框效果
2017/02/01 Javascript
js实现3D图片环展示效果
2017/03/09 Javascript
Bootstrap模态框插件使用详解
2017/05/11 Javascript
ES6学习教程之对象字面量详解
2017/10/09 Javascript
微信小程序wx:for循环的实例详解
2018/10/07 Javascript
jquery.validate自定义验证用法实例分析【成功提示与择要提示】
2020/06/06 jQuery
Python编码时应该注意的几个情况
2013/03/04 Python
浅谈Python对内存的使用(深浅拷贝)
2018/01/17 Python
使用python获取(宜宾市地震信息)地震信息
2019/06/20 Python
在VS2017中用C#调用python脚本的实现
2019/07/31 Python
python并发爬虫实用工具tomorrow实用解析
2019/09/25 Python
python GUI库图形界面开发之PyQt5复选框控件QCheckBox详细使用方法与实例
2020/02/28 Python
伦敦平价潮流珠宝首饰品牌:Astrid & Miyu
2016/10/10 全球购物
中国医药集团国药在线:国药网
2017/02/06 全球购物
法院实习人员自我鉴定
2013/09/26 职场文书
幼儿园数学教学反思
2014/02/02 职场文书
我读书我快乐演讲稿
2014/05/07 职场文书
支行行长竞聘演讲稿
2014/05/15 职场文书
领导干部对照检查材料
2014/08/24 职场文书
出纳工作检讨书范文
2014/12/27 职场文书
重阳节慰问信
2015/02/15 职场文书
2015年电话客服工作总结
2015/05/18 职场文书
pytest实现多进程与多线程运行超好用的插件
2022/07/15 Python