萧山雪木 发表于 2023-4-27 10:04:38

关于文章《爬取知网文献信息》中代码的一些优化

哈喽大家好,我是咸鱼
 
之前写了一篇关于文献爬虫的文章Python爬虫实战(5) | 爬取知网文献信息
 
文章发布之后有很多小伙伴给出了一些反馈和指正,在认真看了小伙伴们的留言之后,咸鱼对代码进行了一些优化
 
优化的代码在文末,欢迎各位小伙伴给出意见和指正
 问题


[*]pycharm 设置 Edge 驱动器的环境报错“module 'selenium.webdriver' has no attribute 'EdgeOptions”
如果浏览器驱动已经下载,而放在了合适的位置(比如添加到环境变量里,或者放在了 python.exe 同级目录中)
 
那就可能是因为你使用的是较老的版本,Edge的选项已经被更新了。 建议更新 selenium 包以获得最佳的Edge选项支持
 
可以通过以下命令更新 selenium,建议更新到 4.6 以上版本
pip install -U selenium 
因为 selenium 4.6 版本之后内置了一个组件:Selenium Manager
 
根据官网介绍,这个 Selenium Manager 可以帮助你获得一个运行 Selenium 的开箱即用的环境
 
如果在 PATH 中没有找到 Chrome、Firefox 和 Edge 的驱动,Selenium Manager的 Beta 1版将为它们配置。不需要额外的配置
 
这就意味着自己不需要再去下载安装浏览器驱动

 
中文文档链接:
https://www.selenium.dev/zh-cn/documentation/webdriver/getting_started/install_drivers/
 

[*]只能爬取20倍数的文献篇数
有位粉丝发现每次爬取都是爬取 20 倍数的文献篇数(20、40、60)。假设要爬取 21 篇,但是却爬到了 40 篇
 
排查的时候发现是代码中的逻辑有一些 bug ,已经优化
 

[*]获取不到网页的 xpath 元素
第一种可能是网页中的 xpath 元素并不是一成不变的,要参考自己的浏览器上的 Xpath。在我这可能是div,在你那可能就不是这个了,所以说需要自己先定位一遍
 
第二种可能是网页加载太慢导致爬虫爬取不到,这种情况的话可以增加等待超时时间
 

[*]关于网页加载太慢导致程序爬取不到元素报超时异常或者元素不存在异常
我的代码中用的都是显示等待 + 强制等待结合的方式。如果还是不行,小伙伴们可以自行设置超时时间
 
优化后代码


 
 下面给出优化后的源码
import timefrom selenium import webdriverfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.common.desired_capabilities import DesiredCapabilitiesfrom urllib.parse import urljoin​​def open_page(driver, theme):    # 打开页面    driver.get("https://www.cnki.net")​    # 传入关键字    WebDriverWait(driver, 100).until(      EC.presence_of_element_located((By.XPATH, '''//*[@id="txt_SearchText"]'''))).send_keys(theme)​    # 点击搜索    WebDriverWait(driver, 100).until(      EC.presence_of_element_located((By.XPATH, "/html/body/div/div/div/div/input"))).click()    time.sleep(3)​    # 点击切换中文文献    WebDriverWait(driver, 100).until(      EC.presence_of_element_located((By.XPATH, "/html/body/div/div/div/div/div/a"))).click()    time.sleep(3)​    # 获取总文献数和页数    res_unm = WebDriverWait(driver, 100).until(EC.presence_of_element_located(      (By.XPATH, "/html/body/div/div/div/div/form/div/div/div/span/em"))).text​    # 去除千分位里的逗号    res_unm = int(res_unm.replace(",", ''))    page_unm = int(res_unm / 20) + 1    print(f"共找到 {res_unm} 条结果, {page_unm} 页。")    return res_unm​​def crawl(driver, papers_need, theme):    # 赋值序号, 控制爬取的文章数量    count = 1​    # 当爬取数量小于需求时,循环网页页码    while count1:                  driver.close()                  driver.switch_to.window(n2)                # 爬完一篇计数加 1                count += 1​                if count > papers_need:                  break                            WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//a[@id='PageNext']"))).click()​​if __name__ == "__main__":    print("开始爬取!")​    # get直接返回,不再等待界面加载完成    desired_capabilities = DesiredCapabilities.CHROME    desired_capabilities["pageLoadStrategy"] = "none"​    # 设置驱动器的环境    options = webdriver.EdgeOptions()​    # 设置chrome不加载图片,提高速度    options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})​    # 设置不显示窗口    options.add_argument('--headless')​    # 创建一个浏览器驱动器    driver = webdriver.Edge(options=options)​    # 输入需要搜索的主题    # theme = input("请输入你要搜索的期刊名称:")    theme = "python"​    # 设置所需篇数    # papers_need = int(input("请输入你要爬取篇数:"))    papers_need = 100​    res_unm = int(open_page(driver, theme))​    # 判断所需是否大于总篇数    papers_need = papers_need if (papers_need
页: [1]
查看完整版本: 关于文章《爬取知网文献信息》中代码的一些优化