Python开发爬虫之动态网页抓取篇:爬取博客评论数据——通过Selenium模拟浏览器抓取
区别于上篇动态网页抓取,这里介绍另一种方法,即使用浏览器渲染引擎。直接用浏览器在显示网页时解析 HTML、应用 CSS 样式并执行 JavaScript 的语句。
这个方法在爬虫过程中会打开一个浏览器加载该网页,自动操作浏览器浏览各个网页,顺便把数据抓下来。用一句简单而通俗的话说,就是使用浏览器渲染方法将爬取动态网页变成爬取静态网页。
我们可以用 Python 的 Selenium 库模拟浏览器完成抓取。Selenium 是一个用于Web 应用程序测试的工具。Selenium 测试直接运行在浏览器中,浏览器自动按照脚本代码做出单击、输入、打开、验证等操作,就像真正的用户在操作一样。
通过Selenium模拟浏览器抓取。最常用 的是 Firefox,因此下面的讲解也以 Firefox 为例,在运行之前需要安装 Firefox 浏 览器。
以爬取《Python 网络爬虫:从入门到实践》一书作者的个人博客评论为例。网址:http://www.santostang.com/2017/03/02/hello-world/
在运行下列代码时,一定要留意自己网络是否畅通,如果网络不好造成浏览器不能正常打开网页及其评论数据,就可能造成爬取失败。
1)找到评论的HTML代码标签。使用Chrome打开该文章页面,右键点击页面,打开“检查”选项。定位到评论数据。此处定位到的评论数据即是浏览器渲染后的数据位置,如图:
2)尝试获取一条评论数据。在原来打开页面的代码数据上,我们可以使用以下代码,获取第一条评论数据。在下面代码中,driver.find_element_by_css_selector是用CSS选择器查找元素,找到class为’reply-content’的div元素;find_element_by_tag_name则是通过元素的tag去寻找,意思是找到comment中的p元素。最后,再输出p元素中的text文本。
相关代码1:
from selenium import webdriver
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary caps=webdriver.DesiredCapabilities().FIREFOX
caps["marionette"]=True
binary=FirefoxBinary(r'E:\软件安装目录\装机必备软件\Mozilla Firefox\firefox.exe') #把上述地址改成你电脑中Firefox程序的地址
driver=webdriver.Firefox(firefox_binary=binary,capabilities=caps)
driver.get("http://www.santostang.com/2017/03/02/hello-world/")
#page=driver.find_element_by_xpath(".//html")
driver.switch_to.frame(driver.find_element_by_css_selector("iframe[title='livere']"))
comment=driver.find_element_by_css_selector('div.reply-content-wrapper') #此处参数字段也可以是'div.reply-content',具体字段视具体网页div包含关系而定
content=comment.find_element_by_tag_name('p')
print(content.text)
#driver.page_source
输出:
在JS 里面也找不到https://api.gentie.163.com/products/ 哪位大神帮忙解答下。谢谢。
代码解析:
1)caps=webdriver.DesiredCapabilities().FIREFOX
由此可知,将上文代码中的caps["marionette"]=True注释掉,代码依旧可以正常运行。
2)binary=FirefoxBinary(r'E:\软件安装目录\装机必备软件\Mozilla Firefox\firefox.exe')
3)driver=webdriver.Firefox(firefox_binary=binary,capabilities=caps)
构建webdriver类。
还可以构建别的类型的webdriver类。
4)driver.get("http://www.santostang.com/2017/03/02/hello-world/")
5)driver.switch_to.frame(driver.find_element_by_css_selector("iframe[title='livere']"))
6)comment=driver.find_element_by_css_selector('div.reply-content-wrapper')
7)content=comment.find_element_by_tag_name('p')
更多代码含义和使用规则请参见官网API和Navigating:http://selenium-python.readthedocs.io/index.html
8)关于driver.switch_to.frame(driver.find_element_by_css_selector("iframe[title='livere']"))中的框架定位及title内容。
可在代码中加入driver.page_source,并且注释掉driver.switch_to.frame(driver.find_element_by_css_selector("iframe[title='livere']"))。可在输出内容中找到(若输出杂乱,不好找出相关内容,可将其复制黏贴到文本文件中,使用Notepad++打开,该软件有前后标签对应显示功能):
(此处只截取了相关内容的末尾部分)
若使用了driver.switch_to.frame(driver.find_element_by_css_selector("iframe[title='livere']")),而再使用driver.page_source进行相关输出,则发现没有上面的iframe标签,证明我们已经将该框架解析完毕,可以进行相关定位获取元素了。
上面我们只是获取了一条评论,如果要获取所有评论,使用循环获取所有评论。
相关代码2:
from selenium import webdriver
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary caps=webdriver.DesiredCapabilities().FIREFOX
caps["marionette"]=True
binary=FirefoxBinary(r'E:\软件安装目录\装机必备软件\Mozilla Firefox\firefox.exe')
driver=webdriver.Firefox(firefox_binary=binary,capabilities=caps)
driver.get("http://www.santostang.com/2017/03/02/hello-world/")
#page=driver.find_element_by_xpath(".//html")
driver.switch_to.frame(driver.find_element_by_css_selector("iframe[title='livere']")) comments=driver.find_elements_by_css_selector('div.reply-content')
for eachcomment in comments:
content=eachcomment.find_element_by_tag_name('p')
print(content.text)
#driver.page_source
输出:
在JS 里面也找不到https://api.gentie.163.com/products/ 哪位大神帮忙解答下。谢谢。
@先生姓张 原来要按照这里的操作才行。。。
在JS 里面也找不到https://api.gentie.163.com/products/ 哪位大神帮忙解答下。谢谢。
@先生姓张 这是网易云上面的一个连接地址,那个服务器都关闭了
在JS 里面也找不到https://api.gentie.163.com/products/ 哪位大神帮忙解答下。谢谢。
测试
为什么我用代码打开的文章只有两条评论,本来是有46条的,有大神知道怎么回事吗?
菜鸟一只,求学习群
lalala1
我来试一试
我来试一试
应该点JS,然后看里面的Preview或者Response,里面响应的是Ajax的内容,然后如果去爬网站的评论的话,点开js那个请求后点Headers -->在General里面拷贝 RequestURL 就可以了
注意代码2中将代码1中的comment=driver.find_element_by_css_selector('div.reply-content-wrapper') 改成了comments=driver.find_elements_by_css_selector('div.reply-content')
elements加了s
以上获取的全部评论数据均属于正常进入该网页,等该网页渲染完获取的全部评论,并未进行点击“查看更多”来加载目前还未渲染的评论。
下面介绍一种能够爬取到所有评论,包括点击完“查看更多”加载的目前还未渲染的评论。
相关代码:
from selenium import webdriver
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
import time caps=webdriver.DesiredCapabilities().FIREFOX
caps["marionette"]=True
binary=FirefoxBinary(r'E:\软件安装目录\装机必备软件\Mozilla Firefox\firefox.exe')
driver=webdriver.Firefox(firefox_binary=binary,capabilities=caps)
driver.get("http://www.santostang.com/2017/03/02/hello-world/")
driver.switch_to.frame(driver.find_element_by_css_selector("iframe[title='livere']")) time.sleep(60)
for i in range(0,10):
try:
load_more=driver.find_element_by_css_selector('div.more-wrapper')
load_more.click()
except:
pass
time.sleep(5)
comments=driver.find_elements_by_css_selector('div.reply-content') for eachcomment in comments:
content=eachcomment.find_element_by_tag_name('p')
print(content.text)
代码解析:
1)time.sleep(60)
延时60秒执行以下代码。
2)load_more=driver.find_element_by_css_selector('div.more-wrapper')中的参数字符串
打开目标网页,等目标网页整体渲染完之后,右键评论区的“查看更多”。
3)load_more.click()
模拟点击“查看更多”按钮,进行完整显示所有评论。
4)之所以在代码中两次使用延时函数,是因为不同网络状况和不同机器环境下可能在打开网页以及点击“查看更多”按钮后不能马上显示评论,所以代码需要等一等,等到页面完全渲染后,再进行评论区数据的收集工作。
因此各延时函数的延时时间长短可视具体情况灵活设置。
输出结果:
在JS 里面也找不到https://api.gentie.163.com/products/ 哪位大神帮忙解答下。谢谢。
@先生姓张 原来要按照这里的操作才行。。。
在JS 里面也找不到https://api.gentie.163.com/products/ 哪位大神帮忙解答下。谢谢。
@先生姓张 这是网易云上面的一个连接地址,那个服务器都关闭了
在JS 里面也找不到https://api.gentie.163.com/products/ 哪位大神帮忙解答下。谢谢。
测试
为什么我用代码打开的文章只有两条评论,本来是有46条的,有大神知道怎么回事吗?
菜鸟一只,求学习群
lalala1
我来试一试
我来试一试
应该点JS,然后看里面的Preview或者Response,里面响应的是Ajax的内容,然后如果去爬网站的评论的话,点开js那个请求后点Headers -->在General里面拷贝 RequestURL 就可以了
现在死在了4.2节上,页面评论是有的,但是XHR里没有东西啊,这是什么情况?有解决的大神吗?
@骨犬 JS
为何静态网页抓取不了? 奇怪了,我按照书上的方法来操作,XHR也是空的啊
@易君召 我的也是空的
你解决问题了吗
@思い亦深 看JS不是XHR
XHR没有显示任何东西啊。奇怪。
找到原因了
caps["marionette"] = True
作者可以解释一下这句话是干什么的吗
@A cat named GitHub 改成 caps["marionette"] = False 可以运行。 目前还没吃透代码,先用着试试
我用的是 pycham IDE,按照作者的写法写的,怎么不行
@A cat named GitHub 找到原因了
caps["marionette"] = True
作者可以解释一下这句话是干什么的吗
对火狐版本有要求吗
@花晨 我的也是提示火狐版本不匹配,你解决了吗
@A cat named GitHub 重装了geckodriver
改成caps["marionette"] = "Windows"
总之就好了
4.3.1 打开Hello World,代码用的作者的,火狐地址我也设置了,为啥运行没反应
from selenium import webdriver
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary caps = webdriver.DesiredCapabilities().FIREFOX
caps["marionette"] = False
binary = FirefoxBinary(r'C:\Program Files\Mozilla Firefox\firefox.exe')
#把上述地址改成你电脑中Firefox程序的地址
driver = webdriver.Firefox(firefox_binary=binary, capabilities=caps)
driver.get("http://www.santostang.com/2017/03/02/hello-world/")
我是番茄
为什么刷新没有XHR数据,评论明明加载出来了
为什么刷新没有XHR数据,评论明明加载出来了
@萌萌哒的小叽叽丶 书里错误很多,留个qq吧
为什么刷新没有XHR数据,评论明明加载出来了
第21条测试评论
第20条测试评论
第19条测试评论
第18条测试评论
第17条测试评论
第16条测试评论
第15条测试评论
第14条测试评论
第13条测试评论
第12条测试评论
第11条测试评论
第10条测试评论
第9条测试评论
第8条测试评论
第7条测试评论
第6条测试评论
第5条测试评论
第4条测试评论
第3条测试评论
第二条测试评论
第一条测试评论
参考书目:唐松,来自《Python 网络爬虫:从入门到实践》
参考书目作者关于本部分的介绍:http://www.santostang.com/2017/09/25/4-3-%E9%80%9A%E8%BF%87-selenium-%E6%A8%A1%E6%8B%9F%E6%B5%8F%E8%A7%88%E5%99%A8%E6%8A%93%E5%8F%96/
Python开发爬虫之动态网页抓取篇:爬取博客评论数据——通过Selenium模拟浏览器抓取的更多相关文章
- Selenium模拟浏览器抓取淘宝美食信息
前言: 无意中在网上发现了静觅大神(崔老师),又无意中发现自己硬盘里有静觅大神录制的视频,于是乎看了其中一个,可以说是非常牛逼了,让我这个用urllib,requests用了那么久的小白,体会到sel ...
- 使用selenium模拟浏览器抓取淘宝信息
通过Selenium模拟浏览器抓取淘宝商品美食信息,并存储到MongoDB数据库中. from selenium import webdriver from selenium.common.excep ...
- Python开发爬虫之静态网页抓取篇:爬取“豆瓣电影 Top 250”电影数据
所谓静态页面是指纯粹的HTML格式的页面,这样的页面在浏览器中展示的内容都在HTML源码中. 目标:爬取豆瓣电影TOP250的所有电影名称,网址为:https://movie.douban.com/t ...
- Python爬虫学习==>第十二章:使用 Selenium 模拟浏览器抓取淘宝商品美食信息
学习目的: selenium目前版本已经到了3代目,你想加薪,就跟面试官扯这个,你赢了,工资就到位了,加上一个脚本的应用,结局你懂的 正式步骤 需求背景:抓取淘宝美食 Step1:流程分析 搜索关键字 ...
- 16-使用Selenium模拟浏览器抓取淘宝商品美食信息
淘宝由于含有很多请求参数和加密参数,如果直接分析ajax会非常繁琐,selenium自动化测试工具可以驱动浏览器自动完成一些操作,如模拟点击.输入.下拉等,这样我们只需要关心操作而不需要关心后台发生了 ...
- 3.使用Selenium模拟浏览器抓取淘宝商品美食信息
# 使用selenium+phantomJS模拟浏览器爬取淘宝商品信息 # 思路: # 第一步:利用selenium驱动浏览器,搜索商品信息,得到商品列表 # 第二步:分析商品页数,驱动浏览器翻页,并 ...
- 爬虫实战--使用Selenium模拟浏览器抓取淘宝商品美食信息
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.common.exce ...
- 使用Selenium模拟浏览器抓取淘宝商品美食信息
代码: import re from selenium import webdriver from selenium.webdriver.common.by import By from seleni ...
- Path通过Selenium模拟浏览器抓取,Windows 64解决selenium.common.exceptions.WebDriverException: Message: 'geckodriver' executable needs to be in PATH.方法
1.下载geckodriver.exe: 下载地址:https://github.com/mozilla/geckodriver/releases请根据系统版本选择下载:(如Windows 64位系统 ...
随机推荐
- MSSQL事务隔离级别详解(SET TRANSACTION ISOLATION LEVEL)
控制到 Transact-SQL 的连接发出的 SQL Server 语句的锁定行为和行版本控制行为. TRANSACT-SQL 语法约定 语法 -- Syntax for SQL Server ...
- JS闭包解析
三点注意事项 JS作用域传送门 JS没有块级作用域,只有全局作用域和局部作用域(函数作用域). JS中的作用域链,内部的作用域可以访问到外部作用域中的变量和方法,而外部作用域不能访问内部作用域的变量和 ...
- FFmpeg 结构体学习(七): AVIOContext 分析
在上文FFmpeg 结构体学习(六): AVCodecContext 分析我们学习了AVCodec结构体的相关内容.本文,我们将讲述一下AVIOContext. AVIOContext是FFMPEG管 ...
- [SQL]LeetCode262.行程和用户 | Trips and Users
SQL架构 Create table If Not Exists Trips (Id )) Create table If Not Exists Users (Users_Id ), Role ENU ...
- [Swift]LeetCode276. 粉刷栅栏 $ Paint Fence
There is a fence with n posts, each post can be painted with one of the k colors. You have to paint ...
- springboot 实战之一站式开发体验
都说springboot是新形势的主流框架工具,然而我的工作中并没有真正用到springboot: 都说springboot里面并没有什么新技术,不过是组合了现有的组件而已,但是自己却说不出来: 都说 ...
- JDBC编程,从入门到精通
今天突然想多说两句,刚刚在知乎看到一个人说,在当今世界,没有技术型驱动的公司,全都是业务型.即便是表面上看似技术型公司,其本质还是为了服务业务.这段话推翻了我以前关于编程的所有看法,觉得颇有道理.下面 ...
- 作为程序员必须掌握的Java虚拟机中的22个重难点
Java虚拟机一直是比较重要的知识点,是Java高级开发必会的.本文为你总结了关于JVM的22个重点.难点,图文并茂的向你展示和JVM有关的重点知识.全文共7000字左右. 概念 虚拟机:指以软件的方 ...
- Python——day11 函数(对象、名称空间、作用域、嵌套、闭包)
一.函数对象 函数名就是存放了函数的内存地址,存放了内存地址的变量都是对象,即 函数名 就是 函数对象 函数对象的应用 1. 可以直接被引用 fn = cp_fn 2 .可以当作函数参数传递 c ...
- linux的tomcat服务器上部署项目的方法
在tomcat服务器上部署项目的前提,是我们已经准备好了tomcat服务器.在CentOs环境下部署JavaWeb环境,部署tomcat服务器在前面的文章中已经总结过了,可以参考以前文章. 一 to ...