使用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和标题.

相关推荐
扎克begod几秒前
JAVA并发编程系列(9)CyclicBarrier循环屏障原理分析
java·开发语言·python
Book_熬夜!21 分钟前
Python基础(九)——正则表达式
python·正则表达式·php
LQS202026 分钟前
基于Python实现一个浪漫烟花秀
开发语言·python
梅如你28 分钟前
python批量对遥感影像进行归一化与数据清洗
开发语言·python
Python私教38 分钟前
Python国产新 ORM 框架 fastzdp_sqlmodel 快速入门教程
java·数据库·python
Python私教39 分钟前
Python ORM 框架 SQLModel 快速入门教程
android·java·python
weixin_419349791 小时前
Python pdf转换为html
python·pdf
吉小雨1 小时前
PyTorch经典模型
人工智能·pytorch·python
可愛小吉1 小时前
Python 课程10-单元测试
开发语言·python·单元测试·tdd·unittest
student.J1 小时前
傅里叶变换
python·算法·傅里叶