php抓取网页动态数据(通过selenium的子模块使用Python爬取网页数据的解决思路)

优采云 发布时间: 2022-04-14 21:28

  php抓取网页动态数据(通过selenium的子模块使用Python爬取网页数据的解决思路)

  1. 文章目的

  我们在使用Python爬取网页数据时,经常会用到urllib模块,它通过调用urllib模块的urlopen(url)方法返回网页对象,并使用read()方法获取url的html内容,然后使用 BeautifulSoup 抓取某个 Tag 内容,结合正则表达式过滤。但是,使用 urllib.urlopen(url).read() 得到的只是网页的静态 html 内容。很多动态数据(如网站访问者数、当前在线人数、微博点赞数等)收录在静态html中,比如我要抓取当前在线人数本bbs网站中的每一部分,不收录静态html页面(不信你尝试查看页面源代码,只有简单的一行)。

  2. 解决方案

  我试过用网上说的浏览器自带的开发者工具(一般是F12弹出相应网页的开发者工具),看网络可以得到动态数据的趋势,但这需要从网上找线索许多网址。我个人觉得太麻烦了。另外,用查看器查看的html内容也收录动态数据,但是有几个问题:如何实时获取查看器的html内容?如何将查看器的html导入python程序?因此,使用查看器的html内容的方法也不符合爬虫的要求。

  偶然发现了selenium模块,发现这个模块可以很方便的根据url加载页面获取session,并找到当前session对应的label。本文将使用 selenium webdriver 模块来获取这些动态生成的内容,尤其是一些重要的动态数据。事实上,selenium 模块的功能并不仅限于爬取网页。它是网络自动化测试的常用模块。它广泛用于 Ruby 和 Java。虽然 Python 用的比较少,但它也是一个非常简单、高效、好用的自动化测试。模块。通过使用selenium的子模块webdriver解决动态数据的抓取问题,也可以对selenium有一个基本的了解,为进一步学习自动化测试打下基础。

  3.实现过程3.1 运行环境

  我在Windows 7系统上安装了Python 2.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 抓取动态数据

  首先导入webdriver子模块

  from selenium import webdriver 获取浏览器的session,浏览器可以使用火狐、Chrome、IE等,这里以火狐为例

  browser = webdriver.Firefox() 加载页面,url本身可以指定合法字符串

  在 browser.get(url) 获取到 session 对象后,为了定位元素,webdriver 提供了一系列的元素定位方法。常用的方法如下:

  ID

  姓名

  班级名称

  关联

  文本

  部分的

  关联

  文本

  标签

  姓名

  路径

  选择器

  比如通过id定位,返回所有元素的列表,lis=borwser.find_elements_by_id_name('kw'')

  按类名定位,lis=find_elements_by_class_name('title_1')

  更详细的定位方法请参考Selenium webdriver(python)教程第3章-定位方法(第一版可百度文库阅读)结合正则表达式过滤相关信息

  一些定位的元素是不想要的,可以用常规过滤掉。比如我想只提取英文字符(包括0-9),并建立如下规律)

  pa=桩(r'\w+')

  为你在 lis 中:

  en=pa.findall(u.lis)

  打印附上会话

  抓取操作完成后,必须关闭session,否则会一直占用内存,影响本机其他进程的运行

  browser.close() 或 browser.quit() 都可以关闭会话。前者只关闭当前会话,浏览器的webdriver没有关闭。后者意味着包括webdriver在内的所有东西都被关闭并添加了异常处理。

  这是必须的,因为有时候session会失败,所以把上面的语句块放到try里面,然后用exception处理异常

  除了 NoSuchElementException:

  assert 0, "can't find element"4. 代码实现

  我通过点击打开链接抓取了指定分区内每个版块的在线人数,并指定了分区id号(0-9),我可以得到版块名称和对应的在线人数,形成一个列表并打印出来,代码如下

  [Python]

  # -*- coding: utf-8 -*-

from selenium import webdriver

from selenium.common.exceptions import NoSuchElementException

import time

import re

def find_sec(secid):

pa=re.compile(r'\w+')

browser = webdriver.Firefox() # Get local session of firefox

browser.get("http://bbs.byr.cn/#!section/%s "%secid) # Load page

time.sleep(1) # Let the page load

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 not equivalent!'

#版面名称有中英文,因此用正则过滤只剩英文的

for i in range(1,max_oindex):

board_en=pa.findall(board[i].text)

result.append([str(board_en[-1]),int(ol_num[i].text)])

browser.close()

return result

except NoSuchElementException:

assert 0, "can't find element"

print find_sec('5') #打印分区5下面的所有板块的当前在线人数列表

  结果如下:

  终端打印效果

  4. 摘要

  无论是在代码简洁性还是执行效率方面,selenium 都非常出色。使用 selenium webdriver 捕获动态数据非常简单高效。也可以进一步利用它来实现数据挖掘、机器学习等深度研究。因此,selenium+python 是值得深入学习的!如果觉得每次都用selenium打开浏览器不方便,可以用phantomjs模拟一个虚拟浏览器,这里不再赘述。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线