技术文档
Selenium文档
动态HTML技术了解
- JS:是网络上最常用的脚本语言,它可以收集用户数据的跟踪数据,不需要重复加载页面直接提交表单,在页面嵌套入多媒体文件,甚至运行网页
- jQuery:是一个快速、简介的JavaScrip框架,封装了JavaScript常用的功能代码
- ajax可以使用网页实现异步更新,可以在不重新加载整个网页的情况下,对网页的某部分进行更新
获取ajax数据的方式
- 直接分析ajax调用的接口,然后通过代码请求这个接口
- 使用Selenium+chromedrive模拟浏览器行为获取数据
方式 | 优点 | 缺点 |
---|---|---|
分析接口 | 直接可以请求到数据。不需要做一些解析工作。代码量少,性能高 | 分析接口比较复杂,特别是一些通过js混淆的接口,要有一定的js功底。容易被发现是爬虫 |
selenium | 直接模拟浏览器的行为。浏览器能请求到的,使用selenium也能请求到。爬虫更稳定 | 代码量多。性能低 |
Selenium+chromdriver获取动态数据
selenium
:是一个web的自动化测试工具,最初是为网站自动化测试而开发的,selenium可以直接运行在浏览器上,它支持所有主流的浏览器,可以接收指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏
chromedriver
:是一个驱动Chrome浏览器的驱动程序,使用他可以驱动浏览器。当然针对不同的浏览器有不同的driver。
安装Selenium
pip install Selenium
Selenium常用的代码语句
webdriver.Chrome()
: 实例化浏览器
get()
: 发送请求
quit()
:退出当前浏览器
close
:关闭当前定位的页面
maximize_window()
:把网页窗口设置最大化
minximize_window()
:把网页窗口设置最小化
save_screenshot
:进行网页截图并保存到当前文件下
Selenium设置代理
from selenium import webdriver
import time
ip = '114.226.246.123:9999'
proxies = webdriver.ChromeOptions() # 创建chrome代理服务器
proxies.add_argument('--proxy-server=%s' % ip) # 该方法是将代理IP加到代理服务器上
driver = webdriver.Chrome(chrome_options=proxies) # 初始化后在进行调用
driver.get('https://www.xicidaili.com/nn/')
定位元素
find_element_by_id
:根据id来查找元素
find_element_by_class_name
: 根据类名查找元素
find_element_by_name
:根据name属性的值来查找元素
find_element_by_tag_name
:根据标签的名字来查找元素
find_element_by_xpath
: 根据xpath语法来获取元素
find_element_by_css_selector
:根据css选择器选取元素
要注意,find_element
:是获取第一个满足条件的元素。find_elements
是获取所有满足条件的元素
操作表单元素
send_keys(value)
:将要填充的数据写进去
click()
:点击事件
clear()
该方法为清除所有的输入
操作checkbox
因为要选中checkbox标签,在网页中是通过鼠标点击的。因此想要选中checkbox标签,那么先选中这个表情,然后执行click事件
from selenium import webdriver
from selenium.webdriver.support.ui import Select
"""
当我们选中的时候,会遇到下拉框选项
这时候我们需要使用到Select来进行选择下拉框来进行操作
"""
driver = webdriver.Chrome()
driver.get('http://www.gxzjy.com/')
tag = Select(driver.find_element_by_name('SearchFrom'))
tag.select_by_index(1) # 根据下拉框索引值来进行查找
模拟登录豆瓣
# -*- coding: utf-8 -*-
# @Time : 2020/2/11 23:29
# @Author : 大数据小J
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get('https://www.douban.com/')
# 页面切换
driver.switch_to.frame(driver.find_element_by_xpath('//div[@class="login"]/iframe'))
time.sleep(1)
driver.find_element_by_class_name('account-tab-account').click()
driver.find_element_by_id('username').send_keys('xxxx')
driver.find_element_by_id('password').send_keys('xxx')
time.sleep(2)
driver.find_element_by_xpath('/html/body/div[1]/div[2]/div[1]/div[5]/a').click()
driver.find_element_by_name('remember').click()
行为链
有时候在页面中的操作可能有很多步,那么这时候可以使用鼠标行为链类ActionChains来完成。比如现在要将鼠标移动到某个元素上并执行点击事件
from selenium.webdriver import ActionChains
actions = ActionChains(driver)
actions.move_to_element(inputTag)
actions.send_keys_to_element(inputTag,'python')
actions.move_to_element(submitTag)
actions.context_click()
actions.click(submitTag)
actions.perform()
Cookie操作
driver.get_cookies()
:获取所有的cookie
driver.delete_cookie('key')
:删除某给cookie
页面等待
现在的网页越来越多采用了 Ajax 技术,这样程序便不能确定何时某个元素完全加载出来了。如果实际页面等待时间过长导致某个dom元素还没出来,但是你的代码直接使用了这个WebElement,那么就会抛出NullPointer的异常。为了解决这个问题。所以 Selenium 提供了两种等待方式:一种是隐式等待、一种是显式等待
隐式等待:调用driver.implicitly_wait。那么在获取不可用的元素之前,会先等待10秒中的时间。
driver.implicitly_wait(10)
显示等待
显示等待:显示等待是表明某个条件成立后才执行获取元素的操作。也可以在等待的时候指定一个最大的时间,如果超过这个时间那么就抛出一个异常。显示等待应该使用selenium.webdriver.support.excepted_conditions期望的条件和selenium.webdriver.support.ui.WebDriverWait来配合完成。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("https://www.baidu.com/")
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "myDynamicElement"))
)
finally:
driver.quit()
虎牙自动化发送随机弹幕
def get_html_data(url):
driver = webdriver.Chrome()
driver.get(url)
driver.find_element_by_link_text('登录').click()
time.sleep(5)
# 根据id值来进行定位
driver.switch_to.frame('UDBSdkLgn_iframe')
time.sleep(5)
driver.find_element_by_xpath('//*[@id="account-login-form"]/div[1]/input').send_keys('xxxx')
driver.find_element_by_xpath('//*[@id="account-login-form"]/div[2]/input').send_keys('xxxxx')
driver.find_element_by_id('login-btn').click()
time.sleep(5)
# 发送弹幕内容
while True:
a = ['主播你好', '符文出装', '你说呢', '就是不告诉你', '我拒绝回答这个问题']
# random.choice是从序列类型(例如列表)中随机返回一个元素
driver.find_element_by_xpath('//*[@id="pub_msg_input"]').send_keys(random.choice(a))
driver.find_element_by_id('msg_send_bt').click()
time.sleep(2)
def main():
url = 'https://www.huya.com/520320'
get_html_data(url)
if __name__ == '__main__':
main()