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

前言:

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

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

最初的思路:

不完整代码如下:

Python 复制代码
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关键字返回结果.

Python 复制代码
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登录的话还是会出现之前的情况.

自动化操作

Python 复制代码
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等待,确保一个按钮元素可见,并点击该按钮。

bs4提取数据

Python 复制代码
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()方法来查找特定元素,然后提取链接和文本信息,并将它们打印出来。

成果展示:

爬取到的url和标题.

相关推荐
哇咔咔哇咔28 分钟前
【科普】conda、virtualenv, venv分别是什么?它们之间有什么区别?
python·conda·virtualenv
CSXB991 小时前
三十四、Python基础语法(文件操作-上)
开发语言·python·功能测试·测试工具
亚图跨际2 小时前
MATLAB和Python及R潜变量模型和降维
python·matlab·r语言·生物学·潜变量模型
IT古董2 小时前
【机器学习】决定系数(R²:Coefficient of Determination)
人工智能·python·机器学习
德育处主任Pro2 小时前
『Django』APIView基于类的用法
后端·python·django
Star Patrick2 小时前
算法训练(leetcode)二刷第十九天 | *39. 组合总和、*40. 组合总和 II、*131. 分割回文串
python·算法·leetcode
武子康3 小时前
大数据-213 数据挖掘 机器学习理论 - KMeans Python 实现 距离计算函数 质心函数 聚类函数
大数据·人工智能·python·机器学习·数据挖掘·scikit-learn·kmeans
写点什么啦3 小时前
使用R语言survminer获取生存分析高风险和低风险的最佳截断值cut-off
开发语言·python·r语言·生存分析·x-tile
武子康3 小时前
大数据-214 数据挖掘 机器学习理论 - KMeans Python 实现 算法验证 sklearn n_clusters labels
大数据·人工智能·python·深度学习·算法·机器学习·数据挖掘
封步宇AIGC4 小时前
量化交易系统开发-实时行情自动化交易-Okex K线数据
人工智能·python·机器学习·数据挖掘