爬取动态HTML:Selenium

技术文档
Selenium文档

动态HTML技术了解

  • JS:是网络上最常用的脚本语言,它可以收集用户数据的跟踪数据,不需要重复加载页面直接提交表单,在页面嵌套入多媒体文件,甚至运行网页
  • jQuery:是一个快速、简介的JavaScrip框架,封装了JavaScript常用的功能代码
  • ajax可以使用网页实现异步更新,可以在不重新加载整个网页的情况下,对网页的某部分进行更新

获取ajax数据的方式

  1. 直接分析ajax调用的接口,然后通过代码请求这个接口
  2. 使用Selenium+chromedrive模拟浏览器行为获取数据
方式 优点 缺点
分析接口 直接可以请求到数据。不需要做一些解析工作。代码量少,性能高 分析接口比较复杂,特别是一些通过js混淆的接口,要有一定的js功底。容易被发现是爬虫
selenium 直接模拟浏览器的行为。浏览器能请求到的,使用selenium也能请求到。爬虫更稳定 代码量多。性能低

Selenium+chromdriver获取动态数据
selenium :是一个web的自动化测试工具,最初是为网站自动化测试而开发的,selenium可以直接运行在浏览器上,它支持所有主流的浏览器,可以接收指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏

chromedriver:是一个驱动Chrome浏览器的驱动程序,使用他可以驱动浏览器。当然针对不同的浏览器有不同的driver。

Chrome版本
Firfox版本

下载chromedrive
淘宝镜像
安装跳转

安装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()

发布了54 篇原创文章 · 获赞 26 · 访问量 6166

猜你喜欢

转载自blog.csdn.net/qq_37662827/article/details/104240303