Skip to content

Latest commit

 

History

History
263 lines (195 loc) · 6.13 KB

File metadata and controls

263 lines (195 loc) · 6.13 KB
Error in user YAML: (<unknown>): found a tab character that violate indentation while scanning a plain scalar at line 3 column 3
---
- oeasy Python 0558
- 这是 oeasy 系统化 Python 教程,从基础一步步讲,扎实、完整、不跳步。愿意花时间学,就能真正学会。
- 本教程同步发布在: 
	- 个人网站: `https://oeasy.org` 
	- 蓝桥云课: `https://www.lanqiao.cn/courses/3584` 
	- GitHub: `https://github.com/overmind1980/oeasy-python-tutorial` 
	- Gitee: `https://gitee.com/overmind1980/oeasypython` 
---

安装环境

回忆

  • 上次我们了解了 selenium
    • selenium是 一个驱动真实浏览器的 工具
    • 支持 各种系统、很多种 主流浏览器
    • 把 浏览器的各种操作
      • 封装成 各种语言的 接口

图片描述

  • 我们使用 python的接口
    • 就可以让 一个真实浏览器 去访问网站
    • 从而 得到爬取的 效果
    • 可以 爬下来些什么 呢?🤔

先复现环境

pip3 install selenium
cd Code
wget https://labfile.oss.aliyuncs.com/courses/3584/geckodriver-v0.35.0-linux64.tar.gz
tar xf geckodriver-v0.35.0-linux64.tar.gz
echo $PATH
sudo cp ./geckodriver /usr/bin
geckodriver
  • 安装驱动和类库

图片描述

  • ctrl + c
    • 结束进程

从文档入手

图片描述

代码

import time

from selenium.webdriver.firefox.service import Service
from selenium import webdriver

service = Service(executable_path="geckodriver")
driver = webdriver.Firefox(service=service)
driver.get("https://www.bilibili.com/video/BV1Es411Z7MH")
time.sleep(10)
title = driver.title
print(title)
driver.quit()
  • 确实可以获得网页标题

图片描述

  • 可以获得整个源文件么?

获得源代码

import time

from selenium.webdriver.firefox.service import Service
from selenium import webdriver

service = Service()
driver = webdriver.Firefox(service=service)
driver.get("https://www.bilibili.com/video/BV1Es411Z7MH")
time.sleep(10)
title = driver.title
print(title)
source = driver.page_source.encode("utf-8")
print(source)
driver.quit()
  • 确实可以爬取到网页

图片描述

  • 可以把这个网页对接到lxml生成一棵etree么?

对接

from selenium.webdriver.firefox.service import Service
from selenium import webdriver
from lxml import etree
import time
service = Service()
driver = webdriver.Firefox(service=service)
driver.get("https://www.bilibili.com/video/BV1Es411Z7MH")
time.sleep(10)
source = driver.page_source
html = etree.HTML(source)
for elem in html.iter():
    print(elem.tag,end=",")
driver.quit()
  • 尝试输出所有的元素

图片描述

xpath

  • 尝试xpath
import time

from selenium.webdriver.firefox.service import Service
from selenium import webdriver
from lxml import etree

service = Service()
driver = webdriver.Firefox(service=service)
driver.get("https://www.bilibili.com/video/BV1Es411Z7MH")
time.sleep(10)
source = driver.page_source
html = etree.HTML(source)
title = html.xpath("/html/head/title")[0]
print(title.text)
driver.quit()
  • 先试试title
    • 无障碍对接
    • 原来用requests获取网页
    • 现在用selenium获取网页
    • 后面都可以对接lxml

图片描述

  • 我想要获得弹幕数据可以吗?

插件

  • 找到基础xpath
    • 并复制

图片描述

  • 设置通用xpath

图片描述

  • 转化为代码

结果

import time

from selenium.webdriver.firefox.service import Service
from selenium import webdriver
from lxml import etree

service = Service()
driver = webdriver.Firefox(service=service)
driver.get("https://www.bilibili.com/video/BV1Es411Z7MH")
time.sleep(10)
source = driver.page_source
html = etree.HTML(source)
lst_span = html.xpath("/html/body/div[2]/div[2]/div[2]/div/div[6]/div[2]/div[1]/div/div/div[2]/a/p")

for span in lst_span:
    print(span.text)
driver.quit()
  • 效果

图片描述

  • time.sleep(10)
    • 延时10秒
    • 想要让他能够访问相应元素时候
    • 就停止延时

询问

图片描述

最终

from selenium.webdriver.firefox.service import Service
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
from lxml import etree

# 初始化 WebDriver
service = Service(executable_path="geckodriver")
driver = webdriver.Firefox(service=service)

# 打开目标网页
url = "https://www.bilibili.com/video/BV1Es411Z7MH"
driver.get(url)

try:
    # 等待特定的 XPath 元素出现
    wait = WebDriverWait(driver, 30)  # 最多等待 30 秒
    element = wait.until(EC.presence_of_element_located((By.XPATH, "/html/body/div[2]/div[2]/div[2]/div/div[6]/div[2]/div[1]/div/div/div[2]/a/p")))

    # 获取页面源代码
    source = driver.page_source
    html = etree.HTML(source)
    
    # 使用 XPath 获取所有匹配的 span 元素
    lst_span = html.xpath("/html/body/div[2]/div[2]/div[2]/div/div[6]/div[2]/div[1]/div/div/div[2]/a/p")

    # 打印每个 span 元素的文本内容
    for span in lst_span:
        print(span.text)
finally:
    # 关闭浏览器
    driver.quit()
  • 结果

图片描述

总结

  • 这次我们尝试用selenium访问了一个网页
    • 原理上 selenium 和 requests发请求 差不多
    • 都是发送请求
    • 只不过requests是直接发送请求
    • selenium用真实的浏览器发送请求
      • 可以动态加载一些后台的一些数据
  • 得到网页源文件之后
    • 都可以xpath进行筛选提取

图片描述

  • 用selenium还可以做些
    • 什么独特的东西么?🤔
  • 下次再说👋

  • 本文来自 oeasy Python 系统教程。
  • 想完整、扎实学 Python,
  • 搜索 oeasy 即可。