Python爬虫之selenium(全套操作)常用的定位元素与常用方法

目录

定位元素方法

爬取网站案例:

常用方法和一些常用操作

获取网页/文本

 操作节点/获取/文本框

 ActionChains(driver)鼠标事件

滑动解锁

登录输入

Python控制鼠标点击

pyHook监听鼠标并打印位置

 

判断节点是否存在

设置代理ip

tab页面切换

窗口切换

html转字符串:

对象转json:

python json.dumps() 中文乱码问题

 python-selenium切换手机模式

selenium-TouchActions接口 行为控制、手势控制

selenium-开启开发者工具(F12)

获取浏览器Network请求和响应


定位元素方法

selenium 安装方法:https://blog.csdn.net/qq_44695727/article/details/106083938

# 查找单个元素: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

# 查找多个元素
find_elements_by_name
find_elements_by_xpath
find_elements_by_link_text
find_elements_by_partial_link_text
find_elements_by_tag_name
find_elements_by_class_name
find_elements_by_css_selector

# 两个私有方法
find_element
find_elements

find_element和find_elements用法:

from selenium.webdriver.common.by import By

driver.find_element(By.XPATH, '//button[text()="Some text"]')
driver.find_elements(By.XPATH, '//button')

XPATH = "xpath"
LINK_TEXT = "link text"
PARTIAL_LINK_TEXT = "partial link text"
NAME = "name"
TAG_NAME = "tag name"
CLASS_NAME = "class name"
CSS_SELECTOR = "css selector"

find_element_by_xpath用法:

绝对路径:login_form = driver.find_element_by_xpath("/html/body/form[1]")
HTML中的第一个表单元素: login_form = driver.find_element_by_xpath("//form[1]")
属性id=loginForm的元素:login_form = driver.find_element_by_xpath("//form[@id='loginForm']")

//div/*                 div下面的所有的元素
//div//p                查找div中的p节点,等于 css_selector里的('div p')
//div/p                查找div的子节点p; 等价于 css_selector里的('div > p')   
//*[@style]        查找所有包含style的所有元素,所有的属性要加@,等于('*[style]'):       
//p[@spec='len']     必须要加引号;等价于 css_selector里的("p[spec='len']")
//p[@id='kw']        xpath中对于id,class与其他元素一视同仁,没有其他的方法

//div/p[2]                   选择div下的第二个p节点 ;等价于css_selector里的div>p:nth-of-type(2)  符合p类型的第二个节点
//div/*[2]                   选择div下第二个元素
//div/p[position()=2]        position()=2   指定第二个位置;  等价于上面的 //div/p[2] 
          position()>=2      位置大于等于2
          position()<2       位置小于2
          position()!=2     位置不等于2
//div/p[last()]              选择div下的倒数第一个p节点; last()倒数第一个
//div/p[last()-1]            选择div下的倒数第二个p节点;
//div/p[position()=last()]   倒数第一个
//div/p[position()=last()-1] 倒数第二个
//div/p[position()>=last()-2]倒数第一个,第二个,第三个
//p | //button                       选择所有的p和button,等价于css_selector里的 p, button
//input[@id='kw' and @class='su']    选择id=kw 并且 class=su的input元素
//p[@spec='len']/..      选择p节点的上层节点       此方法在css_selector中没有
//p[@spec='len']/../..   上层节点的上层节点

爬取网站案例:

from selenium import webdriver


url = 'http://xxxxxxx'


driver = webdriver.Chrome()
# 隐式等待页面加载完
driver.implicitly_wait(20)
# 设置窗口大小
# driver.set_window_size(10, 10)
# 全屏操作
# driver.maximize_window()
driver.get(url)

aList = driver.find_elements_by_xpath('//*[@id="list"]//a')

driver.close()

常用方法和一些常用操作

获取网页/文本

  • driver.page_source                获取整个网页源代码
  • get_attribute("outerHTML")    输出当前标签的本身和标签内的文本内容,如果有子标签,那么子标签本身和标签内的文本内容也将一起输出
  • get_attribute('innerHTML')     获取当前标签的文本内容,如果标签内有子标签,会连子标签本身和子标签内的文本内容一起输出
  • get_attribute('textContent')  == .text
get_attribute:这个标签的某个属性的值。
screentshot:获取当前页面的截图。这个方法只能在driver上使用。
获取所有的cookie:
for cookie in driver.get_cookies():
    print(cookie)

 操作节点/获取/文本框


# 获取标签内的属性值
aList[i].get_attribute('src')

# 获取标签下的文本
aList[i].text

# 关闭页面
driver.close()

# 操作输入框:分为两步。第一步:找到这个元素。
# 第二步:使用send_keys(value),将数据填充进去
inputTag = driver.find_element_by_id('kw')
inputTag.send_keys('python')

# 清除输入框中的内容
inputTag.clear()

# 操作checkbox
# 要选中checkbox标签,在网页中是通过鼠标点击的。因此想要选中checkbox标签,那么先选中这个
# 标签,然后执行click事件
rememberTag = driver.find_element_by_name("rememberMe")
rememberTag.click()

# 选择select,select元素不能直接点击。因为点击后还需要选中元素。这时候selenium就专门
# 为select标签提供了一个类,示例:
from selenium.webdriver.support.ui import Select
# 选中这个标签,然后使用Select创建对象
selectTag = Select(driver.find_element_by_name("jumpMenu"))
# 根据索引选择
selectTag.select_by_index(1)
# 根据值选择
selectTag.select_by_value("http://www.95yueba.com")
# 根据可视的文本选择
selectTag.select_by_visible_text("95秀客户端")
# 取消选中所有选项
selectTag.deselect_all()

# 按钮点击
inputTag = driver.find_element_by_id('su')
inputTag.click()

# 行为链:
# 有时候在页面中的操作可能要有很多步,那么这时候可以使用鼠标行为链类ActionChains来完成。
# 比如现在要将鼠标移动到某个元素上并执行点击事件。那么示例代码如下:

inputTag = driver.find_element_by_id('kw')
submitTag = driver.find_element_by_id('su')

 ActionChains(driver)鼠标事件

actions = ActionChains(driver)  # 实例化一个action对象

# 移动操作
actions.move_to_element(inputTag)  # 把鼠标移动到inputTag元素上,鼠标悬停
actions.move_by_offset(10, 20)  # 从当前鼠标的位置向水平方向移动10个像素,向竖直方向移动20个像素

actions.send_keys_to_element(inputTag,'python')
actions.send_keys("追光者")  # 输入“追光者”
# 全选,复制,粘贴(跨浏览器)
actions.key_down(Keys.CONTROL).send_keys(‘a‘).key_up(Keys.CONTROL)  #ctrl+a
actions.key_down(Keys.CONTROL).send_keys(‘c‘).key_up(Keys.CONTROL)  #ctrl+c
actions.key_down(Keys.CONTROL,search_key).send_keys(‘v‘).key_up(Keys.CONTROL)  #ctrl+v
search_key=driver.find_element_by_id("search-key")
search_key.send_keys(Keys.CONTROL,'v')
key_down,发送,只是按下按键,并不会自动松开,而send_keys发送的键,会实现按下-松开的全过程

# 拖拽操作
actions.drag_and_drop(elem1, elem2).perform()  # 把elem1元素拖拽到elem2上
actions.click_and_hold(elem1).release(elem2).perform()  # 在elem1元素上按下鼠标左键不松,在elem2元素上释放,实现拖拽操作

# 点击操作
actions.click(submitTag)  # 单击
actions.click_and_hold(element)   # 鼠标左键按下不放
actions.context_click(element)  # 右键点击。
actions.double_click(element)  # 鼠标双击。
# 按下鼠标左键在一个元素上,release()释放
ActionChains(driver).click_and_hold(element).perform()
ActionChains(driver).release(element).perform()

actions.perform()  #  执行所有ActionChains 中存储的行为

 更多方法请:http://selenium-python.readthedocs.io/api.html

滑动解锁

time.sleep(3)
    button = driver.find_element_by_xpath('//*[@id="login-slider"]/div[1]/div[2]/div')
    action = ActionChains(driver)  # 实例化一个action对象
    action.click_and_hold(button).perform()  # 鼠标左键按下不放
    action.move_by_offset(400, 0).perform()  # 平行移动鼠标
    action.reset_actions()

登录输入

    inputTag = driver.find_element_by_xpath('//*[@id="loginPage"]/ul/li[1]/div/input')
    inputTag.send_keys('13547584541')

    inputTag2 = driver.find_element_by_xpath('//*[@id="loginPage"]/ul/li[2]/div/input')
    inputTag2.send_keys('734888')

    driver.find_element_by_xpath('//*[@id="loginPage"]/div/button').click()

Python控制鼠标点击

import pyautogui

# 用0.5 秒的时间把光标移动到x,y(437, 151) 位置,y竖向向下增加
pyautogui.moveTo(437, 151, duration=0.5)
pyautogui.click()

pyautogui.click(350, 190, button ='left')# 左击
pyautogui.click(350, 190, button ='right')# 右击

pyHook监听鼠标并打印位置

import pythoncom
import PyHook3 as pyHook


# 监听到鼠标事件调用
def onMouseEvent(event):
    if (event.MessageName == "mouse left down") and (event.MessageName != "mouse move"):
        # 因为鼠标一动就会有很多mouse move,所以把这个过滤下
        x,y = pag.position() #返回鼠标的坐标
        print(x,y)

    return True # 为True才会正常调用,如果为False的话,此次事件被拦截


    # 创建管理器
    hm = pyHook.HookManager()
    # 监听鼠标
    hm.MouseAll = onMouseEvent
    hm.HookMouse()
    # 循环监听
    pythoncom.PumpMessages()

 

判断节点是否存在

def isElementPresent(driver, path):
    #从selenium.common.exceptions 模块导入 NoSuchElementException类
    from selenium.common.exceptions import NoSuchElementException
    try:
        element = driver.find_element_by_xpath(path)
    #原文是except NoSuchElementException, e:
    except NoSuchElementException as e:
        #打印异常信息
        # print(e)
        #发生了NoSuchElementException异常,说明页面中未找到该元素,返回False
        return False
    else:
        #没有发生异常,表示在页面中找到了该元素,返回True
        return True

res = isElementPresent(driver, "/html/div")
if res is True:
    # -----

设置代理ip

有时候频繁爬取一些网页。服务器发现你是爬虫后会封掉你的ip地址。这时候我们可以更改代理ip。更改代理ip,不同的浏览器有不同的实现方式。这里以Chrome浏览器为例:

from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument("--proxy-server=http://110.73.2.248:8123")
driver_path = r"D:\ProgramApp\chromedriver\chromedriver.exe"
driver = webdriver.Chrome(executable_path=driver_path,chrome_options=options)

driver.get('http://xxxxx')

tab页面切换

有时候窗口中有很多子tab页面。这时候肯定是需要进行切换的。selenium提供了一个叫做switch_to_window来进行切换,具体切换到哪个页面,可以从driver.window_handles中找到。示例代码如下

# 打开一个新的页面
driver.execute_script("window.open('https://xxxxxxxx')")
print(driver.window_handles)
# 切换到这个新的页面中
driver.switch_to_window(self.driver.window_handles[1])
print(driver.current_url)
#注意
#虽然在浏览器窗口中切换到了新的页面,但是driver中还没有切换
#如果想要在代码中切换到新的界面,那么应该使用driver.switch_to_window来切换到指定的窗口
#从driver.window_handles中取出具体第几个窗口
#driver.window_handles是一个列表,里面装的都是窗口句柄,它会按照打开的页面顺序来存储窗口的句柄。

更多python其他方法参考另一篇:

https://blog.csdn.net/qq_44695727/article/details/107461597#python%E5%A4%84%E7%90%86%E6%95%B0%E6%8D%AE%E5%B8%B8%E7%94%A8%E6%96%B9%E6%B3%95

窗口切换

# 当前打开的所有窗口
windows = driver.window_handles 

# 转换到最新打开的窗口
driver.switch_to.window(windows[-1])

for handle in windows :  # 切换窗口
    if handle != driver.current_window_handle:
        print('switch to second window', handle)
        driver.close()  # 关闭第一个窗口
        driver.switch_to.window(handle)  # 切换到第二个窗口

html转字符串:

driver.find_element_by_xpath('/html/body').get_attribute("outerHTML").__str__().replace('"', "'")

对象转json:

   

import json

json.loads() 将json转换为dict
json.dumps() 将dict转换为json
json.load() 将json文件转换为dict
json.dump() 将dict转换为json文件 person.json

# 类对象转换为json
person_json = json.dumps(person.__dict__)   
 
# 或者
# 第二个参数传递转换函数,或者使用default=lambda o: o.__dict__
person_json = json.dumps(person, default=convert2json)

# 将person转换为dict
def convert2json(person):
  return {
    'name': person.name,
    'age': person.age,
    'email': person.email
  }

# dict/对象转换为json文件
with open('person.json', 'w') as f:
  json.dump(person, f)

# 将json文件转换为dict/对象
import json
with open('person.json', 'r') as f:
  print(json.load(f))

python json.dumps() 中文乱码问题

json.dumps 序列化时默认使用的ascii编码,想输出真正的中文需要指定ensure_ascii=False:更深入分析,是应为dJSON object 不是单纯的unicode实现,而是包含了混合的unicode编码以及已经用utf-8编码之后的字符串。

写法:

Python2 :json.dumps(odata, ensure_ascii=False).decode('utf8')
                json.dumps(odata,ensure_ascii=False).decode('utf8').encode('gb2312')
Python3 :json.dumps(odata, ensure_ascii=False)

 python-selenium切换手机模式

 # 手机模式
    option = webdriver.ChromeOptions()
    option.add_argument('disable-infobars')
    mobile_emulation = {"deviceName": "iPhone 6"}
    option.add_experimental_option('mobileEmulation', mobile_emulation)

    driver = webdriver.Chrome(chrome_options=option)

selenium-TouchActions接口 行为控制、手势控制

# 行为控制
perform --- 执行所有准备好的Actio

# 手势控制
tap --- 在指定元素上敲击
double_tap --- 在指定元素上双敲击
tap_and_hold --- 在指定元素上点击但不释放
move --- 手势移动指定偏移(未释放)
release --- 释放手势
scroll --- 手势点击并滚动
scroll_from_element --- 从某个元素位置开始手势点击并滚动
long_press --- 长按元素
flick --- 手势滑动
flick_element --- 从某个元素位置开始手势滑动


例:
from selenium.webdriver.common.touch_actions import TouchActions

Action = TouchActions(driver)
Action.double_tap(driver.find_element_by_xpath('//*[@id="bw"]/div[1]/a[2]'))


flick_element(on_element, xoffset, yoffset, speed);
on_element            #操作元素定位
xoffset               #x轴偏移量
yoffset                    #y轴偏移量
speed                     #速度
注意:向上滑动为负数,向下滑动为正数
Action = TouchActions(driver)
"""从button元素像下滑动200元素,以50的速度向下滑动"""
Action.flick_element(button, 0, 200, 50).perform()

selenium-开启开发者工具(F12)

option = webdriver.ChromeOptions()

# 开启开发者工具(F12)
option.add_argument("--auto-open-devtools-for-tabs")

driver = webdriver.Chrome(chrome_options=option)

获取浏览器Network请求和响应

Selenium-获取请求的接口数据信息

Browsermob-Proxy是一个开源的Java编写的基于LittleProxy的代理服务。Browsermob-Proxy的具体流程有点类似与Flidder或Charles。即开启一个端口并作为一个标准代理存在,当HTTP客户端(浏览器等)设置了这个代理,则可以抓取所有的请求细节并获取返回内容。

  • 安装:

直接到项目的github上下载打好的压缩包即可:https://github.com/lightbody/browsermob-proxy/releases ,支持Linux和Windows。

  • 安装对应的python包:

pip install browsermob-proxy
  • 完整代码: 
import json
from browsermobproxy import Server
from selenium.webdriver.chrome.options import Options
from selenium import webdriver


if __name__ == '__main__':
    # 开启Proxy
    server = Server(r'D:\usr\data\browser\browsermob-proxy-2.1.4\bin\browsermob-proxy.bat')
    server.start()
    proxy = server.create_proxy()

    # 配置Proxy启动WebDriver
    chrome_options = Options()
    chrome_options.add_argument('--proxy-server={0}'.format(proxy.proxy))
    # 解决 您的连接不是私密连接问题
    chrome_options.add_argument('--ignore-certificate-errors')
    chrome_options.add_argument('--ignore-urlfetcher-cert-requests')

    driver = webdriver.Chrome(chrome_options=chrome_options)
    driver.implicitly_wait(20)

    proxy.new_har("douyin", options={'captureHeaders': True, 'captureContent': True})

    driver.get(url)

    result = proxy.har


    for entry in result['log']['entries']:
        _url = entry['request']['url']
        # 根据URL找到数据接口
        if "/hotel/list" in _url:
            _response = entry['response']
            _content = _response['content']['text']
            # 获取接口返回内容
            print(_content)
            # 读取信息
            person_json = json.loads(_content)
            hotels = (person_json["data"])["hotels"]
    

    server.stop()

自动化 selenium 库安装使用Python/Java

python爬虫使用 requests-html爬取网页信息以及常用方法

Python一些常用方法-整理

python入门-从安装环境配置到做一个下班打卡提醒.exe小工具

 

  • 17
    点赞
  • 92
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瑶山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值