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

分析

他的代码比较简单,主要有以下的步骤:使用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请求,这里的请求都和要爬取的图片无关。

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

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

滚动条向下第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先需要定义一个具体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爬虫使用Selenium模拟浏览器行为

本文地址: http://www.cppcns.com/jiaoben/python/220990.html

python 模拟浏览器selenium_浅谈python爬虫使用Selenium模拟浏览器行为相关推荐

  1. python表格对齐_浅谈python str.format与制表符\t关于中文对齐的细节问题

    写了一个练手的爬虫...在输出的时候出现了让人很不愉♂悦的问题 像这样: 令人十分难受啊! #------------------------------------------ 在此之前先说一下py ...

  2. python制表符对齐_浅谈python str.format与制表符\t关于中文对齐的细节问题

    写了一个练手的爬虫...在输出的时候出现了让人很不愉♂悦的问题 像这样: 令人十分难受啊! #------------------------------------------ 在此之前先说一下py ...

  3. python编写函数_浅谈Python 函数式编程

    匿名函数lambda表达式 什么是匿名函数? 匿名函数,顾名思义就是没有名字的函数,在程序中不用使用 def 进行定义,可以直接使用 lambda 关键字编写简单的代码逻辑.lambda 本质上是一个 ...

  4. python float 精度_浅谈Python里面小数点精度的控制

    要求较小的精度 round()内置方法 这个是使用最多的,刚看了round()的使用解释,也不是很容易懂.round()不是简单的四舍五入的处理方式. For the built-in types s ...

  5. python数字类型floatcomplexint_浅谈python 四种数值类型(int,long,float,complex)

    Python支持四种不同的数值类型,包括int(整数)long(长整数)float(浮点实际值)complex (复数),本文章向码农介绍python 四种数值类型,需要的朋友可以参考一下. 数字数据 ...

  6. python 迭代器协议_浅谈Python中的生成器和迭代器

    迭代器 迭代器协议 对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么返回一个异常来终止本次迭代.(只能往前走,不能往后退!) 迭代器对象 遵循了(实现了)迭代器协议的对象.(对象内 ...

  7. python可视化工具bokeh_浅谈python可视化包Bokeh

    本文研究的主要是python可视化包Bokeh的相关内容,具体如下. 问题:需要把pandas的数据绘图并通过网页显示,matplotlib需要先保存图像,不合适. 解决:在网上搜了一下,找到一篇介绍 ...

  8. python 调用 .netcore api_浅谈Python调用XBee的API来进行通讯

    浅谈Python调用XBee的API来进行通讯 用python编程来控制串口(COM口),来让一对XBee进行通讯.不需要借助终端来发送和接收数据,增大了XBee使用的灵活性.这才是使用XBee模块的 ...

  9. python static方法_浅谈python 类方法/静态方法

    1.类方法 类方法是从属于"类对象"的方法.类对象可以通过装饰器@classmethod来定义,具体格式如下: @classmethod def 类方法名(cls [, 形参列表] ...

最新文章

  1. 算法训练 K好数(dp+动态规划)
  2. Quaruts II 增量编译
  3. win8计算机可用内存不足,Win8.1玩游戏提示计算机内存不足,Win8.1内存不足怎么办?...
  4. php缩放库,php的缩放图像类使用
  5. getBoundingClientRect()
  6. zabbix分布式监控部署proxy安装
  7. HMM:隐马尔科夫模型 - 学习
  8. php3.2项目怎么创建,php网站后台源码(thinkphp3.2.3开发微信编辑器创建后台)
  9. linux怎么安装台式无线网卡,linux下安装无线网卡
  10. 谷歌中设置utf8编码
  11. ASIHTTPRequest类库的简单介绍
  12. 让猴子游泳,让鸭子爬树
  13. suse11sp3上面配置zypper源
  14. Android RecyclerView 横屏禁用滚动/竖屏开启滚动
  15. java 矩形 旋转_java-旋转矩形并将其在sin波中移动-使用grap...
  16. 位(Bit)与字节(Byte)
  17. 和小鲜肉相比,老程序员该由哪些优势?同时说下我看到的老程序员的三窟
  18. pcm5102a解码芯片音质评测_听歌充电两不误,小米HiFi解码耳放
  19. 使用st-link+keil下载和调试华大单片机的教程
  20. PHP解压ZIP乱码问题

热门文章

  1. python __globals__, __file__
  2. 让你提前认识软件开发(40):既要写好代码,又要写好文档
  3. 使用busybox制作根文件系统(rootfs)
  4. CreateaJointCurve.txt
  5. VS2010 + OpenCL 1.1 @ Windows 7 + AMD HD6870
  6. POJ2940 HDU1489 UVA11054 Wine Trading in Gergovia【Ad Hoc】
  7. I00013 鸡兔同笼
  8. Linux 工具套件 —— binutils、readelf
  9. 记号(notation)的学习
  10. 深度学习基础(八)—— 稀疏自编码器