theme: fancy
前言: Web 数据爬取和自动化已成为许多互联网应用程序的重要组成部分。本文将介绍如何使用 Python 中的两个强大库,即 Selenium 和 Beautiful Soup,来实现自动化操作、网页数据提取以及网页内容分析。并以爬取掘金首页文章列表标题和url为例子进行讲解.
安装和使用Selenium
本文是在python环境下使用selenium,使用浏览器是火狐,系统是win10系统。
python环境的配置这里就不多说了
selenium安装:pip install selenium
Driver安装:https://github.com/mozilla/geckodriver/releases/
环境配置与验证:
找到Pythonx.x -> Scripts 并将Driver内核放到这里.
验证: ```
创建一个 Firefox 浏览器的实例
from selenium import webdriver browser = webdriver.Firefox() ```
运行后成功弹出一个浏览器就表示配置成功.
1. 创建浏览器实例
要使用 Selenium,首先需要创建一个浏览器实例。Selenium 支持多种浏览器,如 Chrome、Firefox、Edge 等。以下是一个创建 Firefox 浏览器实例的示例代码:
``` from selenium import webdriver
创建 Firefox 浏览器实例
driver = webdriver.Firefox() ```
2. 打开和访问网页
创建了浏览器实例后,接下来我们可以使用 get() 方法打开和访问指定的网页:
```
打开指定网页
driver.get("https://example.com") ```
3. find_element() 方法
findelement() 方法是 Selenium 中用于定位元素的主要方法之一。它可以根据不同的定位方式来查找页面上的元素,然后返回一个 WebElement 对象,我们可以对这个对象执行各种操作。 早期的selenium提供了针对id、name、xpath等多种方式的具体方法来定位到具体的元素,比如findelementbyid()、findelementbyname()等,在后续的升级中,这些方法被弃用了,现在统一使用findelement(by=By.ID, value=None)方法,该方法包含了id、name、xpath等定位方式
参数说明
使用示例
以下是使用 **find_element()** 方法的一些示例:
根据 ID 定位元素
``` element_by_id = driver.find_element(By.ID, "element_id") ```
根据名称定位元素
``` element_by_name = driver.find_element(By.NAME, "element_name") ```
根据 CSS 选择器定位元素
``` element_by_css = driver.find_element(By.CSS_SELECTOR, ".element_class") ```
根据 XPath 表达式定位元素
``` element_by_xpath = driver.find_element(By.XPATH, "//div[@class='example']") ```
注意事项
- 不同的定位方式适用于不同的场景,选择合适的方式取决于页面的结构和元素的特点。
- 在选择定位方式时,可以考虑元素的唯一性和稳定性,优先选择 id、name、class 等唯一标识元素的方式。
- XPath 虽然功能强大,但性能相对较慢,应谨慎使用。
- 在实际应用中,可以结合使用多种定位方式来确保准确性和稳定性。
通过 **find_element()** 方法,我们可以定位到页面上的元素,然后进行各种交互和操作,从而实现自动化测试或数据爬取的目标。选择合适的定位方式和元素定位的精确性非常重要,这将影响到自动化操作的稳定性和可靠性。
4. 等待页面元素加载
有时,网页上的元素需要一些时间才能加载完成。Selenium 提供了等待机制,可以等待特定的元素出现或满足特定条件。这有助于处理动态加载的内容。 ```python from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC
显式等待,等待元素出现
element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "element_id")) ) ```
5. 切换窗口和框架
在多窗口或嵌套框架的情况下,Selenium 允许你轻松切换窗口和框架。这对于处理复杂的网页结构非常有用。 ```python
切换到新窗口
driver.switch_to.window(driver.window_handles[1])
切换到 iframe 框架
driver.switch_to.frame("frame_name") ```
6. 执行 JavaScript 代码
有时候,你可能需要在页面上执行 JavaScript 代码。Selenium 允许你使用 **execute_script()** 方法来执行 JavaScript。 ```python
执行 JavaScript 代码,滚动到页面底部
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") ```
7. 处理弹出框
网页中的弹出框(警告框、确认框、提示框)是常见的交互元素。Selenium 提供了 **switch_to.alert** 来处理这些弹出框。 ```python alert = driver.switch_to.alert alert.accept() # 接受弹出框 ``` 在 Selenium 中,处理和管理 Cookies 是非常重要的,特别是在需要模拟登录状态或保持用户会话的情况下。本节将介绍如何使用 Selenium 来获取、保存和加载 Cookies,以及如何利用 Cookies 实现自动登录。
使用 Selenium 保存和加载 Cookies
1. 获取 Cookies 信息
要获取当前页面的 Cookies 信息,可以使用 **get_cookies()** 方法。该方法返回一个包含所有 Cookies 的列表,每个 Cookie 都是一个字典。 ```python
获取当前页面的所有 cookie 信息(返回是字典)
cookies = driver.get_cookies() ```
2. 保存 Cookies 到本地文件
获取 Cookies 后,我们可以将它们保存到本地文件,以备后续使用。这可以使用 Python 的文件操作来实现。 ```python import json
将字典形式的 cookies 转换成 JSON 格式的字符串
json_cookies = json.dumps(cookies)
将 JSON 格式的 cookies 写入到本地文件
with open("cookies.json", "w") as file: file.write(json_cookies) ```
3. 从本地文件加载 Cookies
当需要使用之前保存的 Cookies 时,可以从本地文件加载它们,并将其添加到浏览器中。这可以帮助我们恢复之前的会话状态。 ```python import json
从本地文件加载 JSON 格式的 cookies
with open("cookies.json", "r") as file: json_cookies = file.read()
将 JSON 格式的 cookies 转换成字典形式
cookies = json.loads(json_cookies)
将加载的 cookies 添加到浏览器中
for cookie in cookies: driver.add_cookie(cookie) ```
4. 利用 Cookies 进行自动登录
通过将保存的 Cookies 加载到浏览器中,我们可以实现自动登录网站,而无需重新输入用户名和密码。 ```python
打开需要登录的网页
driver.get("https://example.com/login")
加载之前保存的 cookies
for cookie in cookies: driver.add_cookie(cookie)
刷新页面,已加载的 cookies 将自动登录
driver.refresh() ``` 这样,我们可以利用保存和加载 Cookies 的功能,实现自动登录和保持用户会话状态,从而更轻松地进行网站数据爬取和自动化操作。当需要模拟登录状态时,这是一个非常有用的技巧。
使用 Beautiful Soup 解析 HTML 内容
1. 安装和导入 Beautiful Soup
首先,确保你已经安装了 Beautiful Soup 库。你可以使用以下命令来安装: ```bash pip install beautifulsoup4 ``` 然后,在 Python 代码中导入 Beautiful Soup: ```python from bs4 import BeautifulSoup ```
2. 解析 HTML 页面
使用 Beautiful Soup 解析 HTML 页面通常需要两个步骤:
步骤 1:创建 BeautifulSoup 对象
将 HTML 页面的内容传递给 BeautifulSoup 构造函数,以创建一个 BeautifulSoup 对象: ```python
创建 BeautifulSoup 对象
soup = BeautifulSoup(html_content, 'html.parser') ``` 其中,**html_content** 是包含 HTML 页面内容的字符串。
步骤 2:解析 HTML 树
通过创建的 BeautifulSoup 对象,你可以轻松地遍历和操作 HTML 树。
3. 搜索和提取数据
Beautiful Soup 提供了多种方法来搜索和提取 HTML 中的数据,包括标签、属性和文本。以下是一些常用的方法:
查找单个元素
- find(tag, attributes) :查找指定标签的第一个元素。
- find_all(tag, attributes) :查找所有符合条件的元素,并返回一个列表。
示例: ```python
查找第一个
标签 div_tag = soup.find('div')
查找所有 标签
a_tags = soup.find_all('a') ```
获取标签属性
可以使用 **get()** 方法来获取元素的属性值: ```python
获取 标签的 href 属性值
href_value = a_tag.get('href') ```
获取文本内容
使用 **text** 属性来获取元素的文本内容: ```python
获取
标签的文本内容 text_content = p_tag.text ```
4. 遍历和导航 HTML 树
Beautiful Soup 允许你遍历和导航 HTML 树,访问元素的子元素和父元素。以下是一些常用的方法:
遍历子元素
- contents 属性:获取所有子元素的列表。
- children 属性:获取子元素的迭代器。
示例: ```python
获取所有子元素的列表
children = parent_element.contents
遍历子元素
for child in parent_element.children: print(child) ```
导航父元素
示例: ```python
获取父元素
parent = element.parent ```
5. 进行数据过滤和筛选
Beautiful Soup 还提供了强大的数据过滤和筛选功能,可以帮助你找到符合特定条件的元素。以下是一些方法:
根据 CSS 类名筛选元素
```python
查找具有特定类名的元素
elements = soup.find_all(class_='example-class') ```
根据属性值筛选元素
```python
查找具有特定属性值的元素
elements = soup.find_all(attrs={'data-name': 'example'}) ```
使用正则表达式筛选元素
```python import re
使用正则表达式查找元素
elements = soup.find_all(text=re.compile('example')) ```
实例演示 使用Selenium和bs4爬取掘金首页文章列表
下面将演示一下如何使用 selenium 和 bs4 登录掘金并爬取首页文章列表的标题和url.
首先获取cookie:
```Python def get_cookie(): # 创建一个 Firefox 浏览器的实例 driver = webdriver.Firefox() # 打开指定网页 driver.get('https://juejin.cn/') # 暂停程序执行,等待一段时间(60秒),以确保网页加载完全 time.sleep(30) # 获取当前页面的所有 cookie 信息,并将其存储为字典 dictCookies = driver.get_cookies() # 将字典形式的 cookies 转换成 JSON 格式的字符串 jsonCookies = json.dumps(dictCookies) print(jsonCookies)
# 将 JSON 格式的 cookies 写入到名为 "cookies_juejin.json" 的文件中
with open("cookies_juejin.json", "w") as fp:
fp.write(jsonCookies)
# 关闭浏览器
driver.quit()
``` 在睡眠的30秒内我们要手动登录页面,这样浏览器里就能存入我们的cookie信息了,接着将cookie信息保存至本地,以方便以后读取cookie用以实现自动登录.
加载页面并登录
```Python
创建一个 Firefox 浏览器的实例
browser = webdriver.Firefox()
打开指定网页
browser.get("https://juejin.cn/?utm_source=gold_browser_extension")
删除当前浏览器中的所有 cookie 信息
browser.deleteallcookies()
从名为 "cookies_juejin.json" 的文件中读取之前保存的 JSON 格式的 cookies
with open('cookies_juejin.json', 'r', encoding='utf-8') as f: listCookies = json.loads(f.read())
将读取到的 cookies 添加到当前浏览器中
for cookie in listCookies: browser.add_cookie(cookie)
再次访问网页,这次将包含之前保存的 cookie 信息,实现自动登录
browser.refresh()
等待页面加载完成(可以根据实际情况调整等待时间)
time.sleep(5) ``` **特别强调**:time.sleep(5) **很重要!很重要!很重要!** 因为很多网站的内容是异步加载的,当你网速较差的情况下就会出现请求还没返还结果,程序就已经开始执行下一步了,以至于程序获得的html代码和你手动登录看到的不一样.导致页面结构不同,查找元素时会出现问题. 就例如下面这段代码,当我不执行time.sleep(5)而直接执行gethtml()就会发生输出为空的情况,但多试几次后偶尔能成功找到元素.这就是受网速影响导致元素还没加载就被程序获取页面代码的原因. ```Python def gethtml(): # 获取网页源代码 page_source = browser.page_source # 使用 BeautifulSoup 解析源代码 soup = BeautifulSoup(page_source, 'html.parser') # print(soup) # print(soup.select('.entry-list .item .entry .content-wrapper .content-main .title-row')) for child in soup.select('.content-wrapper .content-main .title-row'): # print(child) print(child.find('a')['href'],child.find('a').text) ``` 上述代码使用bs4里的类选择器去进行筛选标签,最后遍历数组.
显示等待
当然我们也可以用显示等待的方式来解决这个问题,毕竟5s固定等待时长收网速影响未必能达到效果. 显式等待是 Selenium 中一种高级等待技术,它允许你等待特定条件满足后再继续执行后续的操作。相对于隐式等待(Implicit Wait),显式等待更加灵活,可以在等待的过程中定义等待的条件,例如等待某个元素出现、可点击、可见,或者满足自定义的条件。 显式等待的一般步骤如下:
- 导入 WebDriverWait 类和 ExpectedConditions(EC)模块。
- 创建 WebDriverWait 对象,传入 WebDriver 对象和最长等待时间(以秒为单位)作为参数。
- 使用
until()
方法指定等待的条件,直到条件满足或超时为止。 ```python
element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "element_id")) ) ```
WebDriverWait(driver, 10)
:创建了一个 WebDriverWait 对象,等待时间为 10 秒。
EC.presence_of_element_located((By.ID, "element_id"))
:指定等待条件为元素出现,使用 ID 定位方式,元素的 ID 是 "element_id"。
通过以上代码,WebDriver 会等待最长 10 秒,直到页面中具有 ID 为 "element_id" 的元素出现,然后将该元素赋值给 element
变量。
这样,你可以确保在继续执行后续操作之前,等待特定的元素加载完成.这样再使用bs4查找目标元素就不会受网速影响出错了.
运行结果演示图:
将得到的url和掘金的前缀拼接一下就可以成功访问了.