目录

  • 前言
  • 整体思路及环境搭建
  • 爬虫流程
    • 检索部分
    • URL批量爬取
    • 文献详情爬取及excel保存
  • 总结
  • 完整代码
  • 参考内容

前言

之前寒假里为了发专利,写了一篇用python+selenium爬取中国知网专利的攻略,好家伙这隔了几个月老板又让用同一个主题发会议论文了。正好这里优化一下上次的代码,这次不去专利专区了,就看正常的知网检索,爬取一下同一主题相关的期刊、论文。
前文指路:Python-Selenium Webdriver+google chrome浏览器爬取中国知网的文献概述


整体思路及环境搭建

整体思路:就我找文献的思路来看,我会先用手动检索的方式看一下某关键词下检索结果的相关度,在确认关键词的有效性后再做自动化的文献爬取。根据知网前端网页结构,文献的作者、摘要、关键词、发表时间等概述性内容都可以实现自动化的爬取与储存。我会在翻阅摘要与关键词内容后再决定要不要回去知网下载文献(文献一多还是涉及到了批量下载的问题,也是我下一步准备做的代码优化。当然,有个人知网账户的大佬可以无视这一步直接点批量下载就好)

环境搭建:开发环境的话涉及webdriver、python,python相关包还有IDE的配置,这些我在上篇文章里都有说,可以看一下Python-Selenium Webdriver+google chrome浏览器爬取中国知网的文献概述的第一章——使用webdriver的注意事项以及第二章——开始码代码的“引入库”部分。

爬虫流程

这一部分我会讲解代码的各部分功能,并在最后贴上整体代码。此次代码针对的是常规期刊论文的爬取,运行程序后可直接按控制台的提示完成文献列表中 [‘文献名’, ‘发表时间’, ‘作者 机构’, ‘来源’, ‘摘要’, ‘关键词’, ‘url’] 的爬取,并将结果存储在pycharm项目文件夹下的excel文件中。

检索部分

需要引入的库在此系列的前文中已经说过了,文章最后也会贴上整体代码。
先来看检索部分,这里使用webdriver自动化操作网页实现专业检索模式下的文献检索:

driver = webdriver.Chrome()
driver.get('https://kns.cnki.net/kns8/AdvSearch?dbprefix=SCDB&&crossDbcodes=CJFQ%2CCDMD%2CCIPD%2CCCND%2CCISD%2CSNAD%2CBDZK%2CCCVD%2CCJFN%2CCCJD')  # 这个直接就是高级检索的网页
# driver.get('https://cnki.net')
time.sleep(2)# advanced_search = driver.find_element_by_class_name('btn-grade-search')
# advanced_search.click()  # 跳转进入高级检索,后期可维护
# time.sleep(1)major_search = driver.find_element_by_name('majorSearch')
major_search.click()  # 跳转进入专业检索,后期可维护
time.sleep(1)# 输入检索语句,后期可维护
input_key_words = driver.find_element_by_class_name('search-middle').find_element_by_tag_name('textarea')
key_words = input("输入检索语句:")
input_key_words.send_keys(key_words)'''勾一些checkboxXpath选中元素右键复制就行,这里勾一下同义词扩展
'''
check_something = driver.find_element_by_xpath('/html/body/div[2]/div/div[2]/div/div[1]/div[1]/div[2]/div[1]/div[1]/span[3]/label[2]/input')
check_something.click()'''时间范围的选择——通过修改js脚本:移除控件的只读属性然后直接把日期赋值给日历框
'''
js = "$('input:eq(1)').removeAttr('readonly')"
driver.execute_script(js)
js_value = 'document.getElementById("datebox0").value="2010-01-01"'
driver.execute_script(js_value)
time.sleep(1)js2 = "$('input:eq(2)').removeAttr('readonly')"
driver.execute_script(js2)
date_today = time.strftime('%Y-%m-%d')
js_value2 = 'document.getElementById("datebox1").value=' + '"' + date_today + '"'
driver.execute_script(js_value2)
time.sleep(1)search_button = driver.find_element_by_class_name('search-buttons').find_element_by_tag_name('input')
search_button.click()
time.sleep(2)

这里除了由前端排布不同导致的元素修改之外,我还做了几处优化

  1. 首先在元素的选择上,我找到一个偷懒的办法。。在使用F12打开谷歌浏览器的开发者模式后,可以直接右击元素对应的标签来复制它的Xpath, 黏贴到python中后直接使用find_element_by_xpath去找它就行,对应代码块里那句话是check_something = driver.find_element_by_xpath(’/html/body/div[2]/div/div[2]/div/div[1]/div[1]/div[2]/div[1]/div[1]/span[3]/label[2]/input’)
  2. 然后就是对日历控件的编辑:在网页上操作日历控件筛选时间范围的时候使用的是手动点击,而在webdriver中我采用的使用的是修改js脚本的方式,取消控件的只读属性,然后直接将想要的日期input进去,对应的代码找那个修改js脚本的注释就行了。我的代码里时间范围是2010-01-01到运行脚本当天的日期(用import time可以调用方法,用一定格式取到当日日期)。

URL批量爬取

检索完之后,需要整合每篇文献的url到列表里,这是文献详情爬取的前置步骤,具体的url编辑方式需要观察不同网站的url组合方式,中国知网的话用的是dbcode, dbname, filename三个关键词以“&”符号连接,比如:基于运动约束的移动机器人路径规划,正常后面还会有个v关键词带着一串乱码,我猜测是版本代号之类的,但这个不加入也能搜到目标文章。看下代码:

# 现在开始抓取每篇文献的url
results = driver.find_element_by_class_name('pagerTitleCell').find_element_by_tag_name('em').text
num_results = int(results)
num_pages = int(num_results/20) + 1
# print(num_pages)
# print(num_results)
# print(type(num_results))
url_list = []
# 以下为测试代码,抓取目标元素存入字符串变量
# file = driver.find_element_by_class_name('seq').find_element_by_tag_name('input')
# file_attr = file.get_attribute('value')
# print(file_attr)
# print(type(file_attr))
# print(file)
for j in range(num_pages):files = driver.find_elements_by_class_name('seq')k = 0for i in files:target_str = files[k].find_element_by_tag_name('input').get_attribute('value')# print(target_str)# 这里的value以“!”分割dbname和filenamedbcode = target_str[0:4]split_string = target_str.split("!")dbname = split_string[0]filename = split_string[1]url = 'https://kns.cnki.net/kcms/detail/detail.aspx?dbcode=' + dbcode + '&dbname=' + dbname + '&filename=' + filename# print(url)url_list.append(url)k += 1turn_page = driver.find_element_by_class_name('pages').find_elements_by_tag_name('a')[-1]turn_page.click()time.sleep(2)
'''以下循环可以核对抓取到url的准确性format输出,还挺好使的
'''
# y = 1
# for x in url_list:
#     print("{} {}".format(y, x))
#     y += 1

这块的代码和上一篇文章相比没有很大变动,具体代码解释可以参考我的上一篇文章,前面有指路嗯。

文献详情爬取及excel保存

最后一部分,使用beautifulsoup解析url列表里的每一篇文章,并把所需关键内容存入excel中。

# 抓取页面详情的信息,存入excel
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36 Edg/85.0.564.51'}
wb = openpyxl.Workbook()
sheet = wb.active
sheet.title = 'VR——机器人控制相关文献'
ColumnName = ['文献名', '发表时间', '作者 机构', '来源', '摘要', '关键词', 'url']
sheet.append(ColumnName)
for address in url_list:res = requests.get(address, headers=headers)get_page = BeautifulSoup(res.text, 'html.parser')append_list = []title = get_page.find('h1').textappend_list.append(title)rows = get_page.find_all('a')# 瞅一眼每个a标签的text都是啥,确认发表时间和来源该用哪个a标签# for z in rows:#     try:#         print(z.text)#     except:#         print('no text')# exit()publish_time = rows[6].textappend_list.append(publish_time)h3 = get_page.find_all('h3')# h3标签和上文a标签同理# for z in h3:#     try:#         print(z.text)#     except:#         print('no text')author_institute = h3[0].text + ' ' + h3[1].textappend_list.append(author_institute)source = rows[5].textappend_list.append(source)abstract = get_page.find('span', class_='abstract-text').textappend_list.append(abstract)# keywords = get_page.find_all('a', {"target": "_blank"})# keywords = get_page.find('p', class_='keywords')keywords = get_page.select('p[class="keywords"] > a')# keywords = get_page.body.div[2].div[1].div[3].div.div.div[5].p.text# /html/body/div[2]/div[1]/div[3]/div/div/div[5]/p# print(test)kw_list = ''for word in keywords:kw_list += word.text.strip()append_list.append(kw_list)add = addressappend_list.append(add)sheet.append(append_list)wb.save('VR控制相关文献爬取.xlsx')
wb.close()

文献的前端界面中,有一些元素比较难找,此次优化的一个比较关键的点是由beautifulsoup所解析的页面中,层级搜索元素的方式,比如这句话:
keywords = get_page.select(‘p[class=“keywords”] > a’),表示的是寻找class为keywords的p标签下,a标签的内容。

总结

此次代码的改进可以完成常规类型的文献检索和关键内容的爬取储存,这里总结几个爬网页内容的技巧:

  1. 在自动化网页操作过程中,找元素最快的方法是直接右击复制Xpath
  2. 操作控件的过程可通过修改JavaScript实现,比如这里的日历控件
  3. 由BeautifulSoup解析的网页也能实现嵌套select,可以极大提高定位精度,降低重复测试的次数
  4. 实在找不到的标签可以把同名的全print出来看看在第几个就完事了

嗯差不多就是这些了,下一步(如果还有机会的话),可以用通过知网校外登录的界面实现用学校账号登录之后的自动化批量下载操作。


完整代码

# -*- coding:utf-8 -*-
import requests
import time
from selenium import webdriver
from bs4 import BeautifulSoup
import openpyxl# 前序搜索条件的录入使用webdriver,其实也可以手动
'''优化:校外的账号密码登录没看到人机验证且校内cnki主页进去直接处于登录状态这里需要优化一下,后面可以自动下载了
'''
driver = webdriver.Chrome()
driver.get('https://kns.cnki.net/kns8/AdvSearch?dbprefix=SCDB&&crossDbcodes=CJFQ%2CCDMD%2CCIPD%2CCCND%2CCISD%2CSNAD%2CBDZK%2CCCVD%2CCJFN%2CCCJD')  # 这个直接就是高级检索的网页
# driver.get('https://cnki.net')
time.sleep(2)# advanced_search = driver.find_element_by_class_name('btn-grade-search')
# advanced_search.click()  # 跳转进入高级检索,后期可维护
# time.sleep(1)major_search = driver.find_element_by_name('majorSearch')
major_search.click()  # 跳转进入专业检索,后期可维护
time.sleep(1)# 输入检索语句,后期可维护
input_key_words = driver.find_element_by_class_name('search-middle').find_element_by_tag_name('textarea')
key_words = input("输入检索语句:")
input_key_words.send_keys(key_words)'''勾一些checkboxXpath选中元素右键复制就行,这里勾一下同义词扩展
'''
check_something = driver.find_element_by_xpath('/html/body/div[2]/div/div[2]/div/div[1]/div[1]/div[2]/div[1]/div[1]/span[3]/label[2]/input')
check_something.click()'''时间范围的选择——通过修改js脚本:移除控件的只读属性然后直接把日期赋值给日历框
'''
js = "$('input:eq(1)').removeAttr('readonly')"
driver.execute_script(js)
js_value = 'document.getElementById("datebox0").value="2010-01-01"'
driver.execute_script(js_value)
time.sleep(1)js2 = "$('input:eq(2)').removeAttr('readonly')"
driver.execute_script(js2)
date_today = time.strftime('%Y-%m-%d')
js_value2 = 'document.getElementById("datebox1").value=' + '"' + date_today + '"'
driver.execute_script(js_value2)
time.sleep(1)search_button = driver.find_element_by_class_name('search-buttons').find_element_by_tag_name('input')
search_button.click()
time.sleep(2)# 现在开始抓取每篇文献的url
results = driver.find_element_by_class_name('pagerTitleCell').find_element_by_tag_name('em').text
num_results = int(results)
num_pages = int(num_results/20) + 1
# print(num_pages)
# print(num_results)
# print(type(num_results))
url_list = []
# 以下为测试代码,抓取目标元素存入字符串变量
# file = driver.find_element_by_class_name('seq').find_element_by_tag_name('input')
# file_attr = file.get_attribute('value')
# print(file_attr)
# print(type(file_attr))
# print(file)
for j in range(num_pages):files = driver.find_elements_by_class_name('seq')k = 0for i in files:target_str = files[k].find_element_by_tag_name('input').get_attribute('value')# print(target_str)# 这里的value以“!”分割dbname和filenamedbcode = target_str[0:4]split_string = target_str.split("!")dbname = split_string[0]filename = split_string[1]url = 'https://kns.cnki.net/kcms/detail/detail.aspx?dbcode=' + dbcode + '&dbname=' + dbname + '&filename=' + filename# print(url)url_list.append(url)k += 1turn_page = driver.find_element_by_class_name('pages').find_elements_by_tag_name('a')[-1]turn_page.click()time.sleep(2)
'''以下循环可以核对抓取到url的准确性format输出,还挺好使的
'''
# y = 1
# for x in url_list:
#     print("{} {}".format(y, x))
#     y += 1# 抓取页面详情的信息,存入excel
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36 Edg/85.0.564.51'}
wb = openpyxl.Workbook()
sheet = wb.active
sheet.title = 'VR——机器人控制相关文献'
ColumnName = ['文献名', '发表时间', '作者 机构', '来源', '摘要', '关键词', 'url']
sheet.append(ColumnName)
for address in url_list:res = requests.get(address, headers=headers)get_page = BeautifulSoup(res.text, 'html.parser')append_list = []title = get_page.find('h1').textappend_list.append(title)rows = get_page.find_all('a')# 瞅一眼每个a标签的text都是啥,确认发表时间和来源该用哪个a标签# for z in rows:#     try:#         print(z.text)#     except:#         print('no text')# exit()publish_time = rows[6].textappend_list.append(publish_time)h3 = get_page.find_all('h3')# h3标签和上文a标签同理# for z in h3:#     try:#         print(z.text)#     except:#         print('no text')author_institute = h3[0].text + ' ' + h3[1].textappend_list.append(author_institute)source = rows[5].textappend_list.append(source)abstract = get_page.find('span', class_='abstract-text').textappend_list.append(abstract)# keywords = get_page.find_all('a', {"target": "_blank"})# keywords = get_page.find('p', class_='keywords')keywords = get_page.select('p[class="keywords"] > a')# keywords = get_page.body.div[2].div[1].div[3].div.div.div[5].p.text# /html/body/div[2]/div[1]/div[3]/div/div/div[5]/p# print(test)kw_list = ''for word in keywords:kw_list += word.text.strip()append_list.append(kw_list)add = addressappend_list.append(add)sheet.append(append_list)wb.save('VR控制相关文献爬取.xlsx')
wb.close()driver.close()

参考内容

Python-Selenium Webdriver+google chrome浏览器爬取中国知网的文献概述
python selenium 处理时间日期控件
python爬虫beautifulsoup查找定位Select用法

Python-Selenium Webdriver+google chrome浏览器爬取中国知网的文献之二相关推荐

  1. Python-Selenium Webdriver+google chrome浏览器爬取中国知网的文献概述

    Python-Selenium Webdriver+google chrome浏览器爬取中国知网的文献概述 目录 Python-Selenium Webdriver+google chrome浏览器爬 ...

  2. Java使用Selenium+ChromeDriver 爬取中国知网

    Java使用Selenium 爬取中国知网 所需Jar包 中国知网的网页结构,我就不在这里赘述了,自己去看,这里我操作的是爬取博硕论文,只抓取前十页 当Selenium无法调取ChromeDriver ...

  3. Python爬取中国知网文献、参考文献、引证文献

    转载自博客园文章作为学习资料,代码及相关介绍非常详细.原文链接见Python爬取 中国知网文献.参考文献.引证文献

  4. HttpUnit爬取中国知网特定大学网页

    继昨天使用Selenium+ChromeDriver爬取中国知网页面后,今天又想到了一些别的方法,就是HtmlUnit,作为一名萌新程序员,多写写总是好的,操蛋的是,还没想出好的爬取方法. 奉上jar ...

  5. python+selenium爬虫按照名单循环爬取作者知网下载量等信息

    主要爬取下面的表格内的信息如文献篇数,被引用数等等 用的是selenium爬虫 from selenium import webdriver from selenium.common.exceptio ...

  6. python爬取中国知网(中国优秀硕士学位论文数据库)

    笔者这几天受团队任务安排,需要写一份儿关于知网(中国优秀硕士学位论文数据库   入口:http://gb.oversea.cnki.net/kns55/brief/result.aspx?dbPref ...

  7. 爬取中国知网搜索cnki.net

    爬取cnki.net知网搜索页 import requests from lxml.html import etree url = 'https://kns.cnki.net/KNS8/Brief/G ...

  8. Python爬虫:Selenium模拟Chrome浏览器爬取淘宝商品信息

    对于采用异步加载技术的网页,有时候想通过逆向工程的方式来设计爬虫进行爬取会比较困难,因此,要想通过python获取异步加载数据往往可以使用Selenium模拟浏览器的方式来获取. Selenium是一 ...

  9. Python+Selenium动态网页的信息爬取

    录 一.Selenium 1.1 简介 1.2 配置 二.对百度进行自动化测试 2.1 进入百度搜索界面 2.2 自动填充百度网页的查询关键字并完成自动搜索 三.爬取指定网页的名言 3.1 找到元素 ...

  10. 利用selenuim以及无头浏览器爬取9酷网音乐

    利用selenuim以及无头浏览器爬取9酷网音乐 这里使用selenuim爬取的原因也是因为比较直观并且如网页为动态加载时也可以进行爬取,还可以对网站进行操作.这也是selenium的优点所在 需要的 ...

最新文章

  1. 如何利用CIC滤波器、CIC补偿滤波器和半带滤波器设计一个高频数字抽取滤波器
  2. android软件查找号码位置,如何在Android中通过GPS获取位置时获取卫星名称或号码?...
  3. 面向视频原生,火山引擎发布视频云与边缘云软硬一体的新云解决方案
  4. Get和Post请求和对应的参数获取
  5. String中删除空格的7种方法!
  6. java 字符串拆分技巧_在java中如何拆分一个字符串?
  7. c语言在一组数据中找最大值最小值,用c语言输入一组数据,输出最大最小值,求c语言程序讲解: 输入一组数据,求最大值,最小值,和,平均...
  8. 容器安全 - 非特权/非root用户运行容器,提升容器的运行安全
  9. c语言txt操作,C语言文件操作总结
  10. c#推箱子小游戏代码_用C#制作推箱子小游戏
  11. 写的将skb copy/clone后转发到源地址的一段代码
  12. setup factory 设置默认字段的值
  13. 2021-07-05C#/CAD二次开发创建圆弧(4)
  14. js 百度、高德、谷歌、火星、wgs84(2000)地图坐标相互转换的JS实现
  15. Snaker 用户手册
  16. 数据分析-北京房价项目
  17. win7系统如何添加打印机服务器,怎样如何添加打印机驱动步骤
  18. vue页面跳转打开新的窗口
  19. 企业微信收款后可以进行退款吗?如何操作?
  20. linux卸载mysql(完全卸载)

热门文章

  1. Python3—爬虫实现有道在线翻译—(常见错误汇总及解决方法)
  2. 深入浅出曲面的切平面方程和曲面的法线方程
  3. 数据分析师工资高吗?数据分析师6大职业方向+薪资预估
  4. 微信小程序---详情页
  5. Javo 基础 流的分类
  6. 夜神模拟器99%卡死打不开问题
  7. TCP服务器 IO多路复用的实现:select、poll、epoll
  8. oracle查询怎样更效率,Oracle提高查询效率的方法
  9. Cent os 7 使用vnc远程访问
  10. java中double..compare_为什么Java的Double.compare(double,double)实现了它的样子?