使用BS4和Selenium实现高级网页数据采集的实战指南(爬取知乎数据)

2770 篇文章 2 订阅
2606 篇文章 14 订阅

2024软件测试面试刷题,这个小程序(永久刷题),靠它快速找到工作了!(刷题APP的天花板)_软件测试刷题小程序-CSDN博客文章浏览阅读3.4k次,点赞86次,收藏15次。你知不知道有这么一个软件测试面试的刷题小程序。里面包含了面试常问的软件测试基础题,web自动化测试、app自动化测试、接口测试、性能测试、自动化测试、安全测试及一些常问到的人力资源题目。最主要的是他还收集了像阿里、华为这样的大厂面试真题,还有互动交流板块……_软件测试刷题小程序​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502icon-default.png?t=N7T8https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502

最近因为一些原因,需要收集一些知乎的数据进行分析。但当实际操作时却发现遇到了种种问题.首当其冲的就是知乎的反爬机制.最初我的思路是先手动登录,然后提取并存放cookie信息到本地以方便以后使用.然后重新打开后再读取cookie然后刷新页面,结果遇到了和这篇博文一样的情况.

image.png

虽然能成功登录和访问问答,但当我获取搜索结果和点击展开评论时会报错. 经过一段时间的查阅和尝试后写下了这篇博客.

最初的思路:

不完整代码如下:

driver.get('https://www.zhihu.com')
# 暂停程序执行,等待一段时间(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_zhihu.json", "w") as fp:
    fp.write(jsonCookies)
# 关闭浏览器
driver.quit()

# 创建一个 Firefox 浏览器的实例
browser = webdriver.Firefox(options=options)


# 打开指定网页
browser.get("https://www.zhihu.com")
# 删除当前浏览器中的所有 cookie 信息
# browser.delete_all_cookies()
# 从名为 "cookies_juejin.json" 的文件中读取之前保存的 JSON 格式的 cookies
# with open('cookies_zhihu.json', 'r', encoding='utf-8') as f:
#     listCookies = json.loads(f.read())
# # 将读取到的 cookies 添加到当前浏览器中
# for cookie in listCookies:
#     browser.add_cookie(cookie)
# 再次访问网页,这次将包含之前保存的 cookie 信息,实现自动登录
browser.refresh()

使用Selenium来登录知乎,然后将获取到的cookies保存到一个JSON文件中,以便后续使用。在浏览器刷新时加载这些cookies,以实现自动登录。然而会遇到之前所说的那种问题,开始思考是哪里被发现了.

被发现的原因

经过查阅后发现, Selenium容易被检测的主要原因在于它所创建的浏览器指纹与手动操作所创建的浏览器指纹不同。一个常见的检测方法是通过检查window.navigator.webdriver这个关键字。在使用Selenium打开的浏览器中,该关键字的打印结果通常为true,而在正常手动操作的浏览器中,打印结果则为undefined。网站可以通过比较这些关键字的返回值来检测是否有自动化操作的迹象。这就是为什么Selenium容易被检测到的原因之一。

如何绕过

修改window.navigator.webdriver关键字返回结果.

options = webdriver.ChromeOptions()
# 此步骤很重要,设置为开发者模式,防止被各大网站识别出来使用了Selenium
driver = webdriver.Chrome(options=options)
# js注入,修改webdriver返还
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'
})


driver.get('https://www.zhihu.com')

这段代码的关键点在于使用Chrome浏览器的开发者模式,同时通过CDP注入js,将navigator.webdriver的返回值修改为undefined。这样,网站在检测navigator.webdriver时会返回undefined,不再能够轻易检测到Selenium的使用。

然而,因为浏览器指纹很多,这种方法的局限性是显而易见的。不过配合手动登录,已经能获取服务器信任了.而是用cookie登录的话还是会出现之前的情况.

更多的应对机制

像之前提到的指令是在页面加载后执行js注入去修改特征,具有局限性,如果在修改之前网站就检查到该特征也还是会被发现。而参考:java - Selenium webdriver: Modifying navigator.webdriver flag to prevent selenium detection - Stack Overflow 有以下几条比较实用的方式:

  1. options.add_experimental_option("excludeSwitches", ["enable-automation"])

    • 通过add_experimental_option方法添加了一个名为"excludeSwitches"的选项,其值为一个包含"enable-automation"的列表。
    • 这个配置的目的是禁用Chrome中的"enable-automation"开关,这个开关通常用于检测自动化操作。
  2. options.add_experimental_option('useAutomationExtension', False)

    • 通过add_experimental_option方法添加了一个名为"useAutomationExtension"的选项,其值为False。
    • 这个配置用于禁用自动化扩展,这可以防止网站检测到Selenium的自动化操作。
  3. options.add_argument("disable-blink-features=AutomationControlled")

    • 通过add_argument方法添加了一个参数,其值为"disable-blink-features=AutomationControlled"。
    • 这个参数用于禁用Blink引擎中与自动化控制相关的特性,以进一步降低被检测为自动化爬虫的风险。
options = webdriver.ChromeOptions()
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
options.add_argument("disable-blink-features=AutomationControlled")
# 创建一个 Firefox 浏览器的实例
browser = webdriver.Chrome(options=options)
# 打开指定网页
browser.get("https://www.zhihu.com")
# 删除当前浏览器中的所有 cookie 信息
browser.delete_all_cookies()
# 从名为 "cookies_juejin.json" 的文件中读取之前保存的 JSON 格式的 cookies
with open('cookies_zhihu.json', 'r', encoding='utf-8') as f:
    listCookies = json.loads(f.read())
# 将读取到的 cookies 添加到当前浏览器中
for cookie in listCookies:
    browser.add_cookie(cookie)
# 再次访问网页,这次将包含之前保存的 cookie 信息,实现自动登录
browser.refresh()

或是直接通过cmd打开一个浏览器,再通过远程连接的方式去操作,这样无论打开多少个页面也不会被检测到.
 

# Author: 冷月半明
# Date: 2023/10/13
# Description: This script does XYZ.

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 selenium.webdriver.chrome.options import Options
import time
import json
from bs4 import BeautifulSoup

import subprocess

# 远程连接的方式建立浏览器实例
cmd = '"C:\Users\20976\AppData\Local\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222 --user-data-dir="D:\code\Python大数据可视化\selenium_city\ChromeProfile"'
subprocess.run(cmd)
chrome_options = Options()
chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
driver = webdriver.Chrome(options=chrome_options)

driver.get('https://www.zhihu.com')

cmd里第一个参数为浏览器可执行文件位置,第二个参数为占用端口,第三个参数为生成的数据文件存放位置.

自动化操作

def finddata():
    input = driver.find_element(By.ID,'Popover1-toggle')
    input.send_keys('南阳市旅游景点')
    time.sleep(3)
    element =driver.find_element(By.CLASS_NAME, 'Popover')
    button= wait.until(EC.visibility_of_element_located((By.TAG_NAME, 'button')))
    # element.click()
    #  = element.find_element(By., 'button')

    button.click()
    time.sleep(5)

首先查找了一个具有特定ID的输入框,然后在输入框中输入了文本。接着,它等待页面加载,查找了一个具有特定CLASS_NAME的元素,然后使用ExpectedConditions等待,确保一个按钮元素可见,并点击该按钮。

image.png

image.png

bs4提取数据

def gethtml():
    # 获取网页源代码
    page_source = driver.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('.ListShortcut .css-0 .ContentItem-title'):
        print(child.find('div').find('a')['href'],child.find('div').find('span').text)

首先使用driver.page_source获取网页的HTML源代码,然后使用BeautifulSoup库来解析HTML。它遍历了具有特定CSS选择器的元素。在循环中,代码使用.find()方法来查找特定元素,然后提取链接和文本信息,并将它们打印出来。

image.png

成果展示:

爬取到的url和标题.

行动吧,在路上总比一直观望的要好,未来的你肯定会感谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入群: 759968159,里面有各种测试开发资料和技术可以一起交流哦。

最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】

​​​软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

在这里插入图片描述

在这里插入图片描述

  • 27
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值