当前位置:   article > 正文

如何使用python爬虫selenium爬取知网信息以及对数据进行本地化储存和mysql数据库储存_知网爬虫

知网爬虫

一、selenium

1.selenium介绍

selenium的官网(selenium中文网 | selenium安装、selenium使用、selenium中文、selenium下载)给出了详细定义:

Selenium 是web自动化测试工具集,包括IDE、Grid、RC(selenium 1.0)、WebDriver(selenium 2.0)等。

Selenium IDE 是firefox浏览器的一个插件。提供简单的脚本录制、编辑与回放功能。

Selenium Grid 是用来对测试脚步做分布式处理。现在已经集成到selenium server 中了。

RC和WebDriver 更多应该把它看成一套规范,在这套规范里定义客户端脚步与浏览器交互的协议。以及元素定位与操作的接口。

而在python爬虫过程中,为了规避一些网站的反爬机制,我们会选择更智能更灵活的selenium和palywright等工具,这些原本应用于web自动化测试的工具能够很好模拟人工操作,让一些被javascript隐藏的网页信息也能被我们获取。

2.selenium安装

windows系统需要用win+R打开cmd窗口,输入

pip install selenium按下回车键等待安装完成即可

3.selenium在pycharm的环境配置

我们安装selenium之后还需要在pycharm里面进行添加

点击file里面的settings

点击+号

搜索selenium勾选版本然后点击install package等待提示安装完成即可

二、爬虫书写

1.爬虫运行前提及注意事项

此爬虫默认ip登陆可以访问知网,适合高校学子,个人账户需添加登录账号和密码,但鉴于知网的反爬机制,不建议个人爬取,容易被封号。

另外,运行selenium需要安装webdrive才能打开浏览器,不同的浏览器webdrive不同,我这里用的是IE浏览器,NuGet Gallery | Selenium.WebDriver.IEDriver 4.14.0,具体版本和安装方式可以自行搜索。

2.知网页面及爬虫逻辑

知网作为大学文献阅读的必备网站之一,可以给我们提供大量文献帮助,但人手检索文献一篇一篇地复制下载没办法宏观地查看一个领域的学科发展脉络等,所以我们可能需要一些爬虫工具来进行辅助。

我们先看知网的初始页面

我们需要在搜索栏里面输入想要检索的内容,然后点击搜索键,默认的是初级搜索+主题检索,当然你可以改到高级搜索或其他检索方式。

我这里输入的内容是“现代林业”,检索之后默认界面里面按中文、发表时间倒序、“题名作者来源发表时间数据库被引下载”、每页20条显示,这样的检索结果爬不全我想要的内容,我需要对其进行修改,我要点击详情,并让显示改到最大的每页50篇。

此时我想要的关键词和摘要都出现了但这时我发现这里单位和作者位于一个div里面,仅用span包裹,且有的没有作者或者单位或者多个作者或者单位,这个页面的信息储存十分混乱,不太利于我爬取数据后进行处理。

这时我又发现有一个全选-导出与分析-自定义的选项

这个页面里面数据的储存就十分有规律且对作者和单位进行了分割,我还可以自定义想导出的内容

于是就这么愉快的决定了!

3.爬虫函数

首先需要导入,这些是包含数据储存需要的内容,储存的方式不同可能用不到一些内容,如果你要本地建表储存,就不需要pymysql,如果你mysql储存就不需要csv

  1. import time
  2. from selenium import webdriver
  3. from selenium.webdriver.support.ui import WebDriverWait
  4. from selenium.webdriver.support import expected_conditions as EC
  5. from selenium.webdriver.common.by import By
  6. from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
  7. from selenium.webdriver.common.action_chains import ActionChains
  8. import csv
  9. import random
  10. import pymysql

设置驱动环境,设置driver,定义爬取网站,我们可以适当设置不加载图片,减少加载时长。

  1. # get直接返回,不再等待界面加载完成
  2. desired_capabilities = DesiredCapabilities.EDGE
  3. desired_capabilities["pageLoadStrategy"] = "none"
  4. # 设置 Edge 驱动器的环境
  5. options = webdriver.EdgeOptions()
  6. #设置 Edge 不加载图片,提高速度
  7. options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})
  8. # 创建一个 Edge 驱动器
  9. driver = webdriver.Edge(options=options)
  10. #选择网址
  11. driver.get("https://www.cnki.net")

模拟在输入框输入搜索内容并点击

  1. #定义并输入主题,主题词可以换成别的
  2. theme='现代林业'
  3. WebDriverWait(driver, 100).until(
  4. EC.presence_of_element_located((By.XPATH, '''//*[@id="txt_SearchText"]'''))).send_keys(theme)
  5. # 点击搜索
  6. WebDriverWait(driver, 100).until(
  7. EC.presence_of_element_located((By.XPATH, "/html/body/div[2]/div[2]/div/div[1]/input[2]"))).click()
  8. time.sleep(3)

默认是主题检索,也可以通过下面的代码换到其他方式检索,比如全文检索

  1. # 点击主题按钮
  2. WebDriverWait(driver, 100).until(EC.presence_of_element_located((By.XPATH, "/html/body/div[2]/div[2]/div/div[1]/div"))).click()
  3. time.sleep(1)
  4. # 选择内容检索,这里面我以全文检索举例,li[5]代表的是点击“全文”
  5. WebDriverWait(driver, 100).until(EC.presence_of_element_located((By.XPATH, "/html/body/div[2]/div[2]/div/div[1]/div/div[2]/ul/li[5]"))).click()
  6. time.sleep(3)
  7. # 点击搜索
  8. WebDriverWait(driver, 100).until(EC.presence_of_element_located((By.XPATH, "/html/body/div[2]/div[2]/div/div[1]/input[2]"))).click()
  9. time.sleep(5)

对应的 li[n]列表如下

调整一页里面50页,点击详情,看一眼一共多少论文多少页

  1. #控制显示数量为50
  2. WebDriverWait(driver, 100).until(
  3. EC.presence_of_element_located((By.XPATH, "//*[@id='perPageDiv']/div[@class='sort-default']"))).click()
  4. WebDriverWait(driver, 100).until(
  5. EC.presence_of_element_located((By.XPATH, "//*[@id='perPageDiv']/ul/li[@data-val='50']"))).click()
  6. time.sleep(5)
  7. # 点击查看详情
  8. WebDriverWait(driver, 100).until(
  9. EC.presence_of_element_located((By.XPATH, "/html/body/div[2]/div[2]/div[2]/div[2]/div/div[1]/div/div[2]/ul[2]/li[1]"))).click()
  10. time.sleep(3)
  11. # 获取总文献数和页数
  12. res_unm = WebDriverWait(driver, 200).until(
  13. EC.presence_of_element_located((By.XPATH, "/html/body/div[2]/div[2]/div[2]/div[2]/div/div[1]/div/div[1]/span[1]/em"))).text
  14. # 去除千分位里的逗号
  15. res_unm = int(res_unm.replace(",", ''))
  16. page_unm = int(res_unm / 20) + 1
  17. papers_need=res_unm
  18. print(papers_need)
  19. print(page_unm)

爬取的主函数如下,具体看注释解释吧

  1. def crawl(driver, papers_need, theme):
  2. # 赋值序号, 控制爬取的文章数量
  3. count = 1
  4. expect_count=0
  5. # 当爬取数量小于需求时,循环网页页码
  6. while count <= papers_need:
  7. # 等待加载完全,休眠3S
  8. time.sleep(3)
  9. #点击全选键
  10. WebDriverWait(driver, 100).until(EC.presence_of_element_located((By.XPATH, "//*[@id='briefBox']/div[1]/div/div[2]/div[1]/label"))).click()
  11. time.sleep(5)
  12. #看一下这页一共多少篇论文
  13. title_list = WebDriverWait(driver, 200).until(EC.presence_of_element_located((By.XPATH, "/html/body/div[2]/div[2]/div[2]/div[2]/div/div[1]/div/div[2]/div[1]/em"))).text
  14. print(title_list)
  15. title_count=int(title_list)
  16. #点击导出与分析——导出文献——自定义
  17. WebDriverWait(driver, 100).until(EC.presence_of_element_located((By.XPATH, "//*[@id='batchOpsBox']/li[2]"))).click()
  18. WebDriverWait(driver, 100).until(EC.presence_of_element_located((By.XPATH, "//*[@id='batchOpsBox']/li[2]/ul/li[@class='export']"))).click()
  19. WebDriverWait(driver, 100).until(EC.presence_of_element_located((By.XPATH, "//*[@id='batchOpsBox']/li[2]/ul/li[1]/ul/li[13]"))).click()
  20. # 等待新窗口打开并切换到新窗口的上下文
  21. wait = WebDriverWait(driver, 100)
  22. new_window = wait.until(EC.number_of_windows_to_be(2))
  23. driver.switch_to.window(driver.window_handles[-1])
  24. #选择关键词、摘要、发表时间标签
  25. WebDriverWait(driver, 300).until(
  26. EC.presence_of_element_located((By.XPATH, "//*[@id='result']/ul/div/label[@title='Keyword-关键词']"))).click()
  27. WebDriverWait(driver, 300).until(
  28. EC.presence_of_element_located(
  29. (By.XPATH, "//*[@id='result']/ul/div/label[@title='Summary-摘要']"))).click()
  30. WebDriverWait(driver, 300).until(
  31. EC.presence_of_element_located(
  32. (By.XPATH, "//*[@id='result']/ul/div/label[@title='PubTime-发表时间']"))).click()
  33. # 刷新一下等页面更新
  34. WebDriverWait(driver, 300).until(
  35. EC.presence_of_element_located(
  36. (By.XPATH, "//*[@id='result']/ul/div/div/ul/li"))).click()
  37. time.sleep(10)
  38. # 由于知网的原因,需要滑动一下页面才能让信息加载完全,没搞懂知网加载机制,手动模拟了一下发现滑到第20再滑到40条才能50条显示完全
  39. element_xpath = "//*[@id='result']/ul/li[20]"
  40. # 等待元素出现
  41. wait = WebDriverWait(driver, 300)
  42. element = wait.until(EC.presence_of_element_located((By.XPATH, element_xpath)))
  43. # 滚动到元素位置
  44. actions = ActionChains(driver)
  45. actions.move_to_element(element).perform()
  46. time.sleep(5)
  47. element_xpath = "//*[@id='result']/ul/li[40]"
  48. # 等待元素出现
  49. wait = WebDriverWait(driver, 300)
  50. element = wait.until(EC.presence_of_element_located((By.XPATH, element_xpath)))
  51. # 滚动到元素位置
  52. actions = ActionChains(driver)
  53. actions.move_to_element(element).perform()
  54. time.sleep(3)
  55. #设置一个预期在这个页面获取的文献信息数量
  56. expect_count=expect_count+title_count
  57. for i in range(title_count):
  58. if count % title_count != 0:
  59. term = count % title_count # 本页的第几个条目
  60. else:
  61. term = title_count
  62. #从第一条开始爬取,获取html元素并解析
  63. all_elements = WebDriverWait(driver, 300).until(EC.presence_of_element_located((By.XPATH,
  64. f"//*[@id='result']/ul / li[{term}]")))
  65. element_html = all_elements.get_attribute("outerHTML")
  66. #去掉前后的<li>和</li>,把内容根据<br>进行切割
  67. stripped_html = element_html.replace('<li>', '').replace('</li>', '')
  68. # 根据<br>标签对元素进行分割
  69. elements = stripped_html.split('<br>')
  70. # 创建一个空列表来存储内容
  71. content_list = []
  72. # 遍历每个元素,处理并添加到列表中
  73. for element in elements:
  74. element = element.strip() # 去除首尾的空白字符
  75. content_list.append(element) # 将元素添加到列表中
  76. def replace_in_list(my_list, search_string, replace_string):
  77. for element in my_list:
  78. if search_string in element:
  79. # 找到含有 search_string 的元素,去掉该部分并赋值给变量SrcDatabase
  80. new_element1 = element.replace(search_string, replace_string)
  81. new_element = new_element1.replace(" ", "")
  82. # 在原列表中替换元素
  83. my_list[my_list.index(element)] = new_element
  84. break # 找到后退出循环
  85. else: # 如果没有找到含有 search_string 的元素
  86. # 将SrcDatabase设为"无"
  87. new_element = "无"
  88. return new_element
  89. #消去前缀分类赋值
  90. SrcDatabase=replace_in_list(content_list, "SrcDatabase-来源库:", "")
  91. Title=replace_in_list(content_list, "Title-题名:", "")
  92. Author = replace_in_list(content_list, "Author-作者:", "")
  93. Organ = replace_in_list(content_list, "Organ-单位:", "")
  94. Source = replace_in_list(content_list, "Source-文献来源:", "")
  95. Keyword = replace_in_list(content_list, "Keyword-关键词:", "")
  96. Summary = replace_in_list(content_list, "Summary-摘要:", "")
  97. PubTime = replace_in_list(content_list, "PubTime-发表时间:", "")
  98. #形成存储格式
  99. content = [count,SrcDatabase, Title, Author, Organ, Source, Keyword, Summary, PubTime]
  100. print(content)
  101. #插个眼,后面储存数据需要在这里加代码
  102. if count % 10!= 5:
  103. random_number = random.randint(1, 20)
  104. time.sleep(random_number)
  105. # 获取完这页所有的信息后关闭这个网页回到原页面
  106. if term==title_count:
  107. n2 = driver.window_handles
  108. if len(n2) > 1:
  109. driver.close()
  110. driver.switch_to.window(n2[0])
  111. #回到页面并清除全选
  112. #// *[ @ id = "briefBox"] / div[1] / div / div[2] / div[1] / a
  113. WebDriverWait(driver, 300).until(EC.presence_of_element_located(
  114. (By.XPATH, "//*[@id='briefBox']/div[1]/div/div[2]/div[1]/a"))).click()
  115. WebDriverWait(driver, 300).until(EC.presence_of_element_located((By.XPATH,"/html/body/div[2]/div[2]/div[2]/div[2]/div/div[2]/div/div[2]/a[@class='pagesnums']"))).click()
  116. count += 1
  117. if count == papers_need:
  118. break
'
运行

到了这一步基本就完成了,别忘了最关键的一步,运行函数

crawl(driver,papers_need,theme)

4.报错补救方法(待优化)

我运行的时候前2000条基本不会报错,不过因为网络问题和知网有时候会断连等一些问题,2000条左右会爬取失败断连,还没想到更好的补救方法,不过有个好处是我的爬虫方法让50条文章的信息都在一个页面,且一整页信息导出后爬取,爬不出来报错的断点都是50的倍数,页数也是整数。我目前的方法是写了另一个文件,根据报错前最后打印的那条信息记录一下断点是哪里,用第二个爬虫文件翻页到那一页然后从断点出继续爬取。

  1. import time
  2. from selenium import webdriver
  3. from selenium.webdriver.common.keys import Keys
  4. from selenium.webdriver.support.ui import WebDriverWait
  5. from selenium.webdriver.support import expected_conditions as EC
  6. from selenium.webdriver.common.by import By
  7. from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
  8. from selenium.webdriver.common.action_chains import ActionChains
  9. import random
  10. # get直接返回,不再等待界面加载完成
  11. desired_capabilities = DesiredCapabilities.EDGE
  12. desired_capabilities["pageLoadStrategy"] = "none"
  13. # 设置 Edge 驱动器的环境
  14. options = webdriver.EdgeOptions()
  15. #设置 Edge 不加载图片,提高速度
  16. options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})
  17. # 创建一个 Edge 驱动器
  18. driver = webdriver.Edge(options=options)
  19. #选择网址
  20. driver.get("https://www.cnki.net")
  21. #定义并输入主题
  22. theme='现代林业'
  23. WebDriverWait(driver, 100).until(
  24. EC.presence_of_element_located((By.XPATH, '''//*[@id="txt_SearchText"]'''))).send_keys(theme)
  25. # 点击搜索
  26. WebDriverWait(driver, 100).until(
  27. EC.presence_of_element_located((By.XPATH, "/html/body/div[2]/div[2]/div/div[1]/input[2]"))).click()
  28. time.sleep(5)
  29. #/html/body/div[2]/div[2]/div[2]/div[2]/div/div[1]/div/div[2]/div[2]/div/div/div[@class='sort-default']
  30. #//*[@id="perPageDiv"]/div
  31. #//*[@id="perPageDiv"]/ul/li[3]
  32. # 点击查看详情
  33. WebDriverWait(driver, 100).until(
  34. EC.presence_of_element_located((By.XPATH, "/html/body/div[2]/div[2]/div[2]/div[2]/div/div[1]/div/div[2]/ul[2]/li[1]"))).click()
  35. time.sleep(5)
  36. WebDriverWait(driver, 100).until(
  37. EC.presence_of_element_located((By.XPATH, "//*[@id='perPageDiv']/div[@class='sort-default']"))).click()
  38. WebDriverWait(driver, 100).until(
  39. EC.presence_of_element_located((By.XPATH, "//*[@id='perPageDiv']/ul/li[@data-val='50']"))).click()
  40. time.sleep(5)
  41. # 获取总文献数和页数
  42. res_unm = WebDriverWait(driver, 300).until(
  43. EC.presence_of_element_located((By.XPATH, "/html/body/div[2]/div[2]/div[2]/div[2]/div/div[1]/div/div[1]/span[1]/em"))).text
  44. # 去除千分位里的逗号
  45. res_unm = int(res_unm.replace(",", ''))
  46. page_unm = int(res_unm / 50) + 1
  47. papers_need=res_unm
  48. print(papers_need)
  49. print(page_unm)
  50. def crawl(driver, papers_need, theme):
  51. # 赋值序号, 控制爬取的文章数量
  52. #此处count是断点值+1
  53. count = 5951
  54. expect_count=0
  55. # 当爬取数量小于需求时,循环网页页码
  56. while count <= papers_need:
  57. # 等待加载完全,休眠3S
  58. time.sleep(3)
  59. #点击全选键
  60. WebDriverWait(driver, 100).until(EC.presence_of_element_located((By.XPATH, "//*[@id='briefBox']/div[1]/div/div[2]/div[1]/label"))).click()
  61. time.sleep(5)
  62. #看一下这页一共多少篇论文
  63. title_list = WebDriverWait(driver, 200).until(EC.presence_of_element_located((By.XPATH, "/html/body/div[2]/div[2]/div[2]/div[2]/div/div[1]/div/div[2]/div[1]/em"))).text
  64. print(title_list)
  65. title_count=int(title_list)
  66. #点击导出与分析——导出文献——自定义
  67. WebDriverWait(driver, 100).until(EC.presence_of_element_located((By.XPATH, "//*[@id='batchOpsBox']/li[2]"))).click()
  68. WebDriverWait(driver, 100).until(EC.presence_of_element_located((By.XPATH, "//*[@id='batchOpsBox']/li[2]/ul/li[@class='export']"))).click()
  69. WebDriverWait(driver, 100).until(EC.presence_of_element_located((By.XPATH, "//*[@id='batchOpsBox']/li[2]/ul/li[1]/ul/li[13]"))).click()
  70. # 等待新窗口打开并切换到新窗口的上下文
  71. wait = WebDriverWait(driver, 100)
  72. new_window = wait.until(EC.number_of_windows_to_be(2))
  73. driver.switch_to.window(driver.window_handles[-1])
  74. #选择关键词、摘要、发表时间标签
  75. time.sleep(5)
  76. WebDriverWait(driver, 300).until(
  77. EC.presence_of_element_located((By.XPATH, "//*[@id='result']/ul/div/label[@title='Keyword-关键词']"))).click()
  78. time.sleep(5)
  79. WebDriverWait(driver, 300).until(
  80. EC.presence_of_element_located(
  81. (By.XPATH, "//*[@id='result']/ul/div/label[@title='Summary-摘要']"))).click()
  82. time.sleep(5)
  83. WebDriverWait(driver, 300).until(
  84. EC.presence_of_element_located(
  85. (By.XPATH, "//*[@id='result']/ul/div/label[8]"))).click()
  86. #//*[@id="result"]/ul/div/label[8]
  87. # 刷新一下等页面更新
  88. WebDriverWait(driver, 300).until(
  89. EC.presence_of_element_located(
  90. (By.XPATH, "//*[@id='result']/ul/div/div/ul/li[@class='blue']"))).click()
  91. time.sleep(10)
  92. #设置一个预期在这个页面获取的文献信息数量
  93. expect_count=expect_count+title_count
  94. # 定位到目标元素
  95. # 定位元素
  96. element_xpath = "//*[@id='result']/ul/li[20]"
  97. # 等待元素出现
  98. wait = WebDriverWait(driver, 300)
  99. element = wait.until(EC.presence_of_element_located((By.XPATH, element_xpath)))
  100. # 滚动到元素位置
  101. actions = ActionChains(driver)
  102. actions.move_to_element(element).perform()
  103. time.sleep(5)
  104. element_xpath = "//*[@id='result']/ul/li[40]"
  105. # 等待元素出现
  106. wait = WebDriverWait(driver, 300)
  107. element = wait.until(EC.presence_of_element_located((By.XPATH, element_xpath)))
  108. # 滚动到元素位置
  109. actions = ActionChains(driver)
  110. actions.move_to_element(element).perform()
  111. time.sleep(3)
  112. for i in range(title_count):
  113. if count % title_count != 0:
  114. term = count % title_count # 本页的第几个条目
  115. else:
  116. term = title_count
  117. #从第一条开始爬取,获取html元素并解析
  118. all_elements = WebDriverWait(driver, 300).until(EC.presence_of_element_located((By.XPATH,
  119. f"//*[@id='result']/ul / li[{term}]")))
  120. element_html = all_elements.get_attribute("outerHTML")
  121. #去掉前后的<li>和</li>,把内容根据<br>进行切割
  122. stripped_html = element_html.replace('<li>', '').replace('</li>', '')
  123. # 根据<br>标签对元素进行分割
  124. elements = stripped_html.split('<br>')
  125. # 创建一个空列表来存储内容
  126. content_list = []
  127. # 遍历每个元素,处理并添加到列表中
  128. for element in elements:
  129. element = element.strip() # 去除首尾的空白字符
  130. content_list.append(element) # 将元素添加到列表中
  131. def replace_in_list(my_list, search_string, replace_string):
  132. for element in my_list:
  133. if search_string in element:
  134. # 找到含有 search_string 的元素,去掉该部分并赋值给变量SrcDatabase
  135. new_element1 = element.replace(search_string, replace_string)
  136. new_element = new_element1.replace(" ", "")
  137. # 在原列表中替换元素
  138. my_list[my_list.index(element)] = new_element
  139. break # 找到后退出循环
  140. else: # 如果没有找到含有 search_string 的元素
  141. # 将SrcDatabase设为"无"
  142. new_element = "无"
  143. return new_element
  144. #消去前缀分类赋值
  145. SrcDatabase=replace_in_list(content_list, "SrcDatabase-来源库:", "")
  146. Title=replace_in_list(content_list, "Title-题名:", "")
  147. Author = replace_in_list(content_list, "Author-作者:", "")
  148. Organ = replace_in_list(content_list, "Organ-单位:", "")
  149. Source = replace_in_list(content_list, "Source-文献来源:", "")
  150. Keyword = replace_in_list(content_list, "Keyword-关键词:", "")
  151. Summary = replace_in_list(content_list, "Summary-摘要:", "")
  152. PubTime = replace_in_list(content_list, "PubTime-发表时间:", "")
  153. #形成存储格式
  154. content = [count,SrcDatabase, Title, Author, Organ, Source, Keyword, Summary, PubTime]
  155. print(content)
  156. if count % 10!= 5:
  157. random_number = random.randint(1, 3)
  158. time.sleep(random_number)
  159. # 获取完这页所有的信息后关闭这个网页回到原页面
  160. if term==title_count:
  161. n2 = driver.window_handles
  162. if len(n2) > 1:
  163. driver.close()
  164. driver.switch_to.window(n2[0])
  165. #回到页面并清除全选
  166. #// *[ @ id = "briefBox"] / div[1] / div / div[2] / div[1] / a
  167. WebDriverWait(driver, 300).until(EC.presence_of_element_located(
  168. (By.XPATH, "//*[@id='briefBox']/div[1]/div/div[2]/div[1]/a"))).click()
  169. WebDriverWait(driver, 300).until(EC.presence_of_element_located((By.XPATH,"/html/body/div[2]/div[2]/div[2]/div[2]/div/div[2]/div/div[2]/a[@class='pagesnums']"))).click()
  170. count += 1
  171. if count == papers_need:
  172. break
  173. #这里的逻辑是知网文献第一页是1-9,断点一般在9页之后,所以我直接点第九页跳到第九页
  174. #/html/body/div[2]/div[2]/div[2]/div[2]/div/div[2]/div/div[2]/div[9]
  175. time.sleep(5)
  176. wait = WebDriverWait(driver, 300)
  177. click_element = wait.until(EC.presence_of_element_located((By.XPATH, "/html/body/div[2]/div[2]/div[2]/div[2]/div/div[2]/div/div[2]/div[9]")))
  178. click_element.click()
  179. time.sleep(5)
  180. n=1
  181. #这里的逻辑是知网文献点到第九页之后,如果当前页面为t,显示可以点击跳转的最大页面数是t+4,这里面n是点击数,相当于点到9+4*n页
  182. while n<28:
  183. time.sleep(5)
  184. wait = WebDriverWait(driver, 300)
  185. click_element = wait.until(EC.presence_of_element_located((By.XPATH, "/html/body/div[2]/div[2]/div[2]/div[2]/div/div[2]/div/div[2]/div[10]")))
  186. click_element.click()
  187. n+=1
  188. else:
  189. page_now=117
  190. # 这里的逻辑是如果断点页不是9+4*n,我们需要点下一页下一页下一页到想要的那个页面
  191. while page_now<120:
  192. time.sleep(5)
  193. wait = WebDriverWait(driver, 300)
  194. #/html/body/div[2]/div[2]/div[2]/div[2]/div/div[1]/div/div[1]/span[4]/a
  195. click_element = wait.until(EC.presence_of_element_located((By.XPATH, "/html/body/div[2]/div[2]/div[2]/div[2]/div/div[2]/div/div[2]/a[@class='pagesnums']")))
  196. click_element.click()
  197. page_now+=1
  198. else:
  199. crawl(driver, papers_need, theme)

三、数据储存

1.本地建表及储存

我们爬取数据后假如需要储存在本地,就需要在一开始建表(假如已经建过了这步可以省略)

  1. import csv
  2. # 建立一个表格,路径E:\test\test.csv和文件名自己修改
  3. with open(r'E:\test\test.csv', 'w', encoding='UTF8', newline='') as f:
  4. writer = csv.writer(f)
  5. # 写入表头,按自己想爬的内容修改
  6. header = [ '标题', '作者及机构', '发表时间', '来源', '摘要', '关键词']
  7. writer.writerow(header)
  8. print('over')
'
运行

储存时则需要在爬虫函数中插入一段代码(返回去找一下我插眼的地方)

  1. with open(r'E:\test\test.csv', 'a', encoding='UTF8', newline='') as f:
  2. writer = csv.writer(f)
  3. writer.writerow(content)
  4. print("信息写入完成")

2.mysql建表及储存

如果爬取的数据需要储存在mysql里面:

mysql的安装我就省略了,注意我这里用的库是pymysql,像selenium一样配置pymysql到pycharm

配置好之后我们得确保有要储存的库和表,我这里的代码是检查是否有这个库和表,没有就建一个

  1. # 连接 MySQL 数据库服务器
  2. cnx = pymysql.connect(user='root', password='123456', port=3306, host='localhost')
  3. cursor = cnx.cursor()
  4. # 检查数据库是否存在,不存在则创建
  5. db_name = 'courseDate'
  6. cursor.execute(f"SHOW DATABASES LIKE '{db_name}'")
  7. if cursor.fetchone() is None:
  8. cursor.execute(f"CREATE DATABASE {db_name}")
  9. print(f"Database {db_name} created successfully.")
  10. else:
  11. print(f"Database {db_name} already exists.")
  12. # 关闭连接
  13. cursor.close()
  14. cnx.close()
  15. # 连接数据库
  16. cnx = pymysql.connect(user='root', password='123456', port=3306, host='localhost', database=db_name)
  17. cursor = cnx.cursor()
  18. # 检查表是否存在,不存在则创建
  19. table_name = 'cuishuhan'
  20. cursor.execute(f"SHOW TABLES LIKE '{table_name}'")
  21. if cursor.fetchone() is None:
  22. cursor.execute(f"""CREATE TABLE {table_name} (
  23. count INT, # 整数类型的'count'列
  24. SrcDatabase VARCHAR(255),
  25. Title VARCHAR(255),
  26. Author VARCHAR(255),
  27. Organ VARCHAR(255),
  28. Source VARCHAR(255),
  29. Keyword VARCHAR(255),
  30. Summary TEXT,
  31. PubTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP
  32. )""")
  33. print(f"Table {table_name} created successfully.")
  34. else:
  35. print(f"Table {table_name} already exists.")
  36. # 提交更改
  37. cnx.commit()
  38. # 关闭连接
  39. cursor.close()
  40. cnx.close()

储存就简单多了

  1. # 连接到MySQL数据库
  2. def connect_to_mysql():
  3. try:
  4. conn = pymysql.connect(user='root', password='123456', host='localhost',
  5. port=3306, database='courseDatet')
  6. cursor = conn.cursor()
  7. cursor.execute('SELECT 1') # 进行一次查询操作来检查连接是否活着
  8. if cursor.fetchone()[0] == 1: # 如果查询结果为1,那么连接是活动的
  9. print("成功连接到MySQL数据库")
  10. return conn
  11. except pymysql.Error as e:
  12. print(f"Failed to connect to database: {e}")
  13. return None
  14. # 将数据插入到MySQL数据库的表中
  15. def insert_into_mysql(conn, content):
  16. try:
  17. cursor = conn.cursor()
  18. query = "INSERT INTO cuishuhan (count,SrcDatabase,Title,Author,Organ,Source,Keyword,Summary,PubTime) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s)"
  19. cursor.execute(query, content)
  20. conn.commit()
  21. print("数据插入成功")
  22. except pymysql.Error as e:
  23. print(e)
  24. # 主函数
  25. def chucun(content):
  26. conn = connect_to_mysql()
  27. if conn is not None:
  28. insert_into_mysql(conn, content)
  29. else:
  30. print("无法连接到MySQL数据库")
  31. chucun(content)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/843569
推荐阅读
相关标签
  

闽ICP备14008679号