动态网页爬取
动态网页爬取
动态网页是指在网页中依赖JavaScript脚本动态加载数据的网页
一.selenium和PhantomJS
1.selenium
selenium是一个Web的自动化测试工具,selenium可以直接运行在浏览器上.selenium可以根据用户的指令,让浏览器自动加载页面,获取需要的数据集,甚至页面截屏
2.PhantomJS
PhantomJS是一个基于Webkit的"无界面"浏览器,它会把网站加载到内存并执行页面上的JavaScript
二.selenium和PhantomJS的基本应用
1.入门操作
# 导入 webdriver
from selenium import webdriver
driver=webdriver.PhantomJS()
driver.get("http://www.baidu.com")
from IPython.display import Image
Image(filename="./data/7_1.png",width=500)
# 获取页面id=wrapper的文本内容
data=driver.find_element_by_id("wrapper").text
print(data)
新闻
hao123
地图
视频
贴吧
学术
登录
设置
更多产品
百度
把百度设为主页关于百度About Baidu百度推广
©2019 Baidu 使用百度前必读 意见反馈 京ICP证030173号 京公网安备11000002000001号
# 页面标题
driver.title
'百度一下,你就知道'
#生成当前页面快照并保存
driver.save_screenshot("baidu.png")
True
# 页面源代码
code=driver.page_source
# 输入框输入长城页面快照
driver.find_element_by_id("kw").send_keys(u"黄河")
driver.save_screenshot("baidu.png")
True
Image("./data/huagnhe.png",width=500)
# id="su"定位百度搜索按钮,click()方法模拟点击
driver.find_element_by_id("su").click()
driver.save_screenshot("huagnhe.png")
True
Image("./data/huanghessuo.png",width=500)
# 调用键盘按键操作,导入Keys
from selenium.webdriver.common.keys import Keys
# Ctrl+A 全选输入框内容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,"a")
# Ctrl+X 剪切输入框内容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,"x")
# 搜索关键字 cnblogs
driver.find_element_by_id("kw").send_keys("cnblogs")
# 回车
driver.find_element_by_id("kw").send_keys(Keys.RETURN)
import time
time.sleep(2)
driver.save_screenshot("cnblogs.png")
True
driver.find_element_by_id("kw").clear()
driver.get_cookies()
[{'domain': '.baidu.com',
'httponly': False,
'name': 'H_PS_PSSID',
'path': '/',
'secure': False,
'value': '1424_28938_21117_28518_28775_28723_28963_28839_28585_26350_20718'},
{'domain': 'www.baidu.com',
'httponly': False,
'name': 'BDSVRTM',
'path': '/',
'secure': False,
'value': '121'},
{'domain': '.baidu.com',
'httponly': False,
'name': 'PSINO',
'path': '/',
'secure': False,
'value': '3'},
{'domain': 'www.baidu.com',
'httponly': False,
'name': 'BD_CK_SAM',
'path': '/',
'secure': False,
'value': '1'},
{'domain': '.baidu.com',
'httponly': False,
'name': 'delPer',
'path': '/',
'secure': False,
'value': '0'},
{'domain': '.baidu.com',
'expires': '周五, 17 5月 2019 02:19:36 GMT',
'expiry': 1558059576,
'httponly': False,
'name': 'BDORZ',
'path': '/',
'secure': False,
'value': 'B490B5EBF6F3CD402E515D22BCDA1598'},
{'domain': 'www.baidu.com',
'expires': '周四, 16 5月 2019 03:02:48 GMT',
'expiry': 1557975768,
'httponly': False,
'name': 'H_PS_645EC',
'path': '/',
'secure': False,
'value': '6725Fa4Yc55tGt8zh8jHbs2ZY45WPynfwfuBIO5RZf0nVb%2BOA%2BBgHk7OWH4'},
{'domain': 'www.baidu.com',
'expires': '周日, 26 5月 2019 02:19:21 GMT',
'expiry': 1558837161,
'httponly': False,
'name': 'BD_UPN',
'path': '/',
'secure': False,
'value': '14314454'},
{'domain': '.baidu.com',
'expires': '周一, 08 5月 2051 02:19:21 GMT',
'expiry': 2567125161,
'httponly': False,
'name': 'BIDUPSID',
'path': '/',
'secure': False,
'value': '5FE631E068565B8A82FAC8531C66714C'},
{'domain': '.baidu.com',
'expires': '周二, 03 6月 2087 05:33:27 GMT',
'expiry': 3705456807,
'httponly': False,
'name': 'PSTM',
'path': '/',
'secure': False,
'value': '1557973160'},
{'domain': '.baidu.com',
'expires': '周二, 03 6月 2087 05:33:27 GMT',
'expiry': 3705456807,
'httponly': False,
'name': 'BAIDUID',
'path': '/',
'secure': False,
'value': '733D46B74DA248350E4BA03C62585819:FG=1'}]
driver.current_url
'https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=cnblogs&oq=%25E9%25BB%2584%25E6%25B2%25B3&rsv_pq=f355a99900009917&rsv_t=315dmRio7%2FtH7UbVSM4jMdMbwE8%2F5aBA177BAl5fJ1DAtlLBJ3Mkhn77lzM&rqlang=cn&rsv_enter=0&inputT=612&rsv_sug1=2&rsv_sug7=001&rsv_sug3=10&rsv_sug4=612&rsv_sug=2'
driver.close()
driver.quit()
2.定位UL元素
selenium的WebDriver中提供了各种方法来定位页面上的元素:
- find_element_by_id
- find_element_by_name
- find_element_by_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
from selenium import webdriver
driver=webdriver.PhantomJS()
driver.get("https://www.csdn.net/")
data=driver.find_element_by_id("nav").text
print(data)
推荐
关注
专题
程序人生
前端
架构
区块链
编程语言
数据库
游戏开发
移动开发
运维
人工智能
安全
云计算/大数据
研发管理
物联网
计算机基础
音视频开发
其他
print(driver.title)
CSDN-专业IT技术社区
element=driver.find_element_by_id("csdn-toolbar")
print(element)
from selenium.webdriver.common.by import By
element=driver.find_element(by=By.ID,value="csdn-toolbar")
<selenium.webdriver.remote.webelement.WebElement (session="39191c90-778a-11e9-8b8c-bf2cdaa64b0a", element=":wdc:1557977119102")>
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
driver=webdriver.PhantomJS()
driver.get("https://leetcode.com/accounts/login/")
driver.find_element_by_id("username-input").send_keys("xxxxxxxxx")
driver.find_element_by_id("password-input").send_keys("xxxxxxxxx")
driver.find_element_by_xpath("//span[@class='btn-content__lOBM']").click()
time.sleep(3)
driver.save_screenshot("Leecode.png")
driver.quit()
3.页面等待
显式等待
显式等待指定某个条件,然后设置最长等待时间.如果这个时间结束时还没有找到元素,就会抛出异常
显式等待使用WebDriverWait
类,其构造函数定义如下:
WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)
参数说明:
- driver:WebDriver的驱动程序(IE,Chrome,Firefox等浏览器或远程)
- timeout:最长超时时间,默认以秒为单位
- poll_frequency:休眠时间的间隔(步长)时间,默认为0.5
- ignored_exceptions:超时后的异常信息,默认情况下抛出
NoSuchElementException
异常
WebDriverWait
对象一般与until()
或until_not()
方法配合使用,说明如下:
- until(method,message=""):调用该方法提供的驱动程序作为一个参数,直到返回值不为False
- until_not(method,message=""):调用该方法提供的驱动程序作为一个参数,直到返回值为False
from selemium import webdriver
from selemium.webdriver.common.by import By
# WebDriverWait库,负责循环等待
from selenium.webdriver.support.ui import WebDriverWait
# expected_conditions类,负责条件触发
from selenium.webdriver.support import expected_conditions as EC
driver=webdriver.PhantomJS()
driver.get("http://www.baidu.com")
try:
# 查找页面元素,超过10秒则报出异常
element=WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,"myElement")))
finally:
driver.quit()
隐式等待
隐式等待就是设置一个全局的最大等待时间,单位为秒.在定位元素时,对所有元素设置超时时间,超出了设置时间则抛出异常
隐式等待使用implicitly_wait
方法,它使得WebDriver在查找一个Element或者Element数组时,每隔一段特定的时间就会轮询一次DOM,直到Element或数组被发现为止
隐式等待的时间一旦设置,这个设置会在WebDriver对象实例的整个生命周期起作用
from selenium import webdriver
driver=webdriver.PhantomJS()
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")
dynamic_element=driver.find_element_by_id("myElement")