selenium的基本使用
动态网页抓取问题
某些网站采用动态网页技术,页面中的数据通过执行js向dom树中动态增加元素,这样的网页我们无法直接从网页源代码中获取数据,因为这是客户端(浏览器)执行js后动态添加的
无头浏览器
一个无界面的浏览器,可以执行与其他浏览器同样的操作,接受网页数据并渲染,执行js文件,动态的生成dom树的数据,还可以执行一些浏览器的操作,例如在一个输入框中输入内容,下拉滚动条等。
Phantom JS
无头浏览器,下载地址https://phantomjs.org/download.html,下载对应版本即可
chromedriver
可以通过该driver操作浏览器,从而使用python自动化程序操作浏览器,下载地址http://npm.taobao.org/mirrors/chromedriver/,下载与当前安全的chrome版本一致的驱动即可, 浏览器菜单/帮助/关于可以查看信息。
selenium
selenium 是一个 web自动化测试工具,它可以直接运行在浏览器中,支持主流的浏览器,包括无头浏览器PhantomJS,以及通过chromeDriver驱动的chrome。
安装selenium
pip install selenium
安装即可
项目结构
selenium包文件结构如下
selenium/ common/ webdriver/ android blackberry chrome common edge firefox ie opera phantomjs remote safari support webkitgtk # __init__.py __pycache__
从文件目录可以看出,selenium 提供了各种浏览器的驱动支持,不同的浏览器选择不同引擎即可。common和support包中提供一些工具类。
访问一个网页
from selenium import webdriver # 核心对象,大部分数据在该对象上调用 import time driver = webdriver.Chrome(r"D:chromedriver.exe") # 下载的chrome驱动 # 如果是PhantomJS使用 # driver = webdriver.PhantomJS("phantomJS/bin/phantomJS.exe") # 下载的phantomJS可执行文件 driver.set_window_size(1280, 1024) # 设置窗口大小 driver.get("https://cn.bing.com/") # 执行后并没有结果,异步执行,将来会加载内容到driver对象中 time.sleep(3) # 加载数据,渲染页面需要时间,简单等待3秒 # 页面加载完毕,截图看一下,提供图片地址参数, png格式及后缀 driver.save_screenshot("o://bingshot.png") driver.quit() # 关闭浏览器进程,虽然看不到,但是会启动一个浏览器进程,需要关闭
执行后可以看到图片,及加载后的页面,页面加载完毕, 可以操作这个dom树中的数据,即使这个数据是执行JS程序添加。
提取页面元素
from selenium import webdriver # 核心对象,大部分数据在该对象上调用 from urllib import parse # 用来url编码 driver = webdriver.Chrome(r"D:chromedriver.exe") # 下载的chrome驱动 url = "https://cn.bing.com/search?" + parse.urlencode({"q":"垃圾分类"}) driver.get(url) time.sleep(3) # 简单等待3秒,加载完毕再提取数据 try: ele = driver.find_element_by_id(ele_name) # 通过id搜索一个元素 if ele.is_display(): # 判断是否呈现了,否则加载不出来 print(ele)
这里通过标签id获取标签信息,此外还提供了其他的方法,可以实现更加灵活数据提取方式。可以使用dir函数获取这些方法。
print(*dir(driver), sep="\n") # 提取方法,注意element 和 elements find_elements find_elements_by_class_name find_elements_by_css_selector find_elements_by_id find_elements_by_link_text find_elements_by_name find_elements_by_partial_link_text find_elements_by_tag_name find_elements_by_xpath # 通过xpath获取
通过以上方法可以获取指定得标签对象,标签对象同样包好id,tag_name,属性,标签位置,大小等数据,
input = browser.find_element_by_class_name('zu-top-add-question') print(inputget_attribute('class')) print(input.text) print(input.id) print(input.location) print(input.tag_name) print(input.size)
获取访问数据
除了获取网页内部的元素信息,还可以获取当前访问网站的cookie等信息,也可以删除和设置新的cookie。
execute execute_async_script # 异步执行js脚本信息 execute_script add_cookie delete_cookie get_cookie get_cookies
模拟登录,模拟点击
在此以模拟扣扣邮箱登录,登录地址为https://mail.qq.com/,
from selenium import webdriver from urllib import parse import random from selenium.webdriver.common.keys import Keys driver = webdriver.Chrome(r"D:\开源项目\12306project\chromedriver.exe") driver.set_window_size(1280, 1024) url = "https://mail.qq.com" driver.get(url) # qq邮箱使用frame标签,首先切换到登录页面 driver.switch_to.frame("login_frame") # 模拟点击切换登录方式的按钮,也就是使用账号密码登录的方式,而不是二维码登录 button = driver.find_element_by_id("switcher_plogin") button.click() user = driver.find_element_by_id("u") user.send_keys("172****299") passwd = driver.find_element_by_id("p") passwd.send_keys("13****154") # 输入完毕,直接敲击回车,或者换取登录按钮标签点击 passwd.send_keys(Keys.ENTER) # 成功登录后,可以直接使用get——cookie获取登录信息,交给其他程序使用这个登录状态。 cookies = driver.get_cookies() print(*cookies, sep="\n") # 查看登录信息
使用requests登陆爬取数据
cookie信息获取后,获取了登录状态,使用该cookie,可以通过requests模块使用该cookie信息获取内容
from request import RequseCookieJar import request from selenium import webdriver cookie_jar = ReqesutCookieJar() # 遍历上面程序获取的cookie,添加再reques对象中 for cookie in cookies: cookie_jar.set(cookie["name"], cookie["value"]) headers = { "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" } url = "https://mail.qq.com" response = request.get(url, headers=headers, cookie=cookie_jar)