网页抓取数据(通过利用selenium的子模块webdriver的使用解决思路(图))
优采云 发布时间: 2021-10-05 00:04网页抓取数据(通过利用selenium的子模块webdriver的使用解决思路(图))
1. 文章 目的
我们在使用Python爬取网页数据时,经常会用到urllib模块,它通过调用urllib模块的urlopen(url)方法返回网页对象,并使用read()方法获取网页的html内容url,然后使用 BeautifulSoup 抓取某个 Label 内容,结合正则表达式过滤。但是,您使用 urllib.urlopen(url).read() 得到的只是网页的静态 html 内容。很多动态数据(如网站访问量、当前在线人数、微博点赞数等)都没有收录在静态html中,比如我想抓取当前在线点击人数打开 bbs网站 链接的每个部分。静态html网页不收录(不信你试试看页面源码,只有简单的一行)。
2. 解决方案
我已经尝试了网上说的使用浏览器自带的开发者工具(一般是F12弹出相应网页的开发者工具)查看网上动态数据的趋势,但这需要从多方面寻找线索网址。个人觉得太麻烦。另外,查看器查看的html内容也收录动态数据,但是有几个问题:如何实时获取查看器的html内容?如何将查看器的html内容导入python程序?所以使用查看器的html内容的方法也不符合爬虫程序的要求。偶然发现了selenium模块,发现这个模块可以很方便的根据url加载页面获取session,找到当前session对应的tag。本文将使用 selenium webdriver 模块来获取这些动态生成的内容,尤其是一些重要的动态数据。事实上,selenium 模块的功能不仅限于抓取网页。它是网络自动化测试的常用模块。它在 Ruby 和 Java 中被广泛使用。Python虽然使用的相对较少,但它也是一个非常简单、高效、易用的自动化测试。模块。通过使用selenium的子模块webdriver解决动态数据的捕获问题,你也可以对selenium有一个基本的了解,为进一步学习自动化测试打下基础。它是网络自动化测试的常用模块。它在 Ruby 和 Java 中被广泛使用。Python虽然使用的相对较少,但它也是一个非常简单、高效、易用的自动化测试。模块。通过使用selenium的子模块webdriver解决动态数据的捕获问题,你也可以对selenium有一个基本的了解,为进一步学习自动化测试打下基础。它是网络自动化测试的常用模块。它在 Ruby 和 Java 中被广泛使用。Python虽然使用的相对较少,但它也是一个非常简单、高效、易用的自动化测试。模块。通过使用selenium的子模块webdriver解决动态数据的捕获问题,你也可以对selenium有一个基本的了解,为进一步学习自动化测试打下基础。
3. 实现过程 3.1 运行环境
我在windows 7系统上安装了Python2.7版本,使用的是Python(X,Y)的IDE,安装的Python库没有自带selenium,直接在Python程序中导入selenium会提示有没有这个模块,联网状态下cmd直接输入pip install selenium,系统会找到Python的安装目录,直接下载解压安装这个模块。终端提示完成后,可以查看C:\Python27\Lib\site-packages目录下是否有selenium模块。这个目录取决于你安装 Python 的路径。如果有 selenium 和 selenium-2.47.3.dist-info 两个文件夹,则可以在 Python 程序中加载模块。使用 webdriver 捕获动态数据
首先从 selenium import webdriver 导入 webdriver 子模块以获取浏览器会话。浏览器可以使用Firefox、Chrome、IE等,这里以Firefox为例,browser = webdriver.Firefox()加载页面,url本身指定合法字符串。但是 browser.get(url) 获取到 session 对象后,为了定位元素,webdriver 提供了一系列的元素定位方法,常用的有以下几种方式: idnameclass-namelinktextpartiallinktexttagnamexpathcssselector 例如通过 id 定位,返回一个列表所有元素, lis=borwser.find_elements_by_id_name('kw'') 是通过class-name来定位的, lis=find_elements_by_class_name('title_1') 更详细的定位方法,请参考selenium webdriver(python)教程-定位方法部分(第一版)第三章可在百度文库中查看)结合正则表达式过滤相关信息。定位后有些元素不需要,用正则表达式过滤掉即可。比如我想只提取英文字符(包括0-9),在lis中为u创建如下Regular pa=pile(r'\w+'):en=pa.findall(u.lis)print en 关闭会话,执行fetch操作后,必须关闭会话,否则会一直占用内存。运行browser.close()或本机其他进程的浏览器.quit()可以关闭会话,前者只是关闭当前会话,浏览器的webdriver没有关闭,后者是关闭包括webdriver在内的所有东西。
我通过点击打开链接抓取指定分区每个版块的在线用户数,并指定分区id号(0-9),可以得到该版块的名称和对应的在线人数,形成一个列表并打印出来,代码如下
[python]查看平原
#-*- 编码:utf-8 -*- from selenium import webdriver from mon.exceptions import NoSuchElementException import time import re def find_sec(secid): pa=pile(r'\w+') browser = webdriver.Firefox() #获取firefox浏览器的本地会话.get("!section/%s "%secid) #加载页面 time.sleep(1) #让页面加载 result=[] try: #获取页面名称和在线人数, 形成列表 board=browser.find_elements_by_class_name('title_1') ol_num=browser.find_elements_by_class_name('title_4') max_bindex=len(board) max_oindex=len(ol_num) assert max_bindex==max_oindex,'index 不等价!' #The板名有中文和英文,所以只剩下i in range(1,max_oindex) 的英文进行常规过滤: board_en=pa.findall(board[i].text) result.append([str(board_en[-1]) ),int( ol_num[i].text)]) 浏览器。close() return result except NoSuchElementException: assert 0, "can't find element"print find_sec('5') #打印分区5下所有版块的当前在线用户列表
操作结果如下:
终端打印效果4.总结
Selenium 在代码简洁性和执行效率方面非常出色。使用 selenium webdriver 捕获动态数据非常简单高效。还可以进一步利用这个来实现数据挖掘、机器学习等深度研究,所以selenium+python是值得深入研究的!如果觉得每次都用selenium打开浏览器不方便,可以用phantomjs模拟虚拟浏览器,这里不再赘述。