python+selium模拟浏览器,在知网高级检索页面进行全文检索,获取页面数据并录入excel(非下载文献)

目录

  • 序言
  • 函数模块介绍
    • 创建模拟浏览器对象
    • 只需要执行一次的部分
    • 需要批量执行的重复操作部分
    • 获取网页数据
    • 录入excel
    • 主函数
  • 本地文件结构
  • 全部代码
  • 结果预览
    • 控制台
    • 文件

序言

场景是在知网高级检索界面中,选择报纸–>点击包含非学术文献–>改成全文模式–>点击检索页发表年度–>获取括号内的数字和对应的年份
在这里插入图片描述

需要三个库,都可以用pip install轻松下载,稍微麻烦点儿的是需要去下载个对应版本的chromedriver.exe驱动,放到python或者Anaconda的文件夹目录下,然后添加环境变量(这部分报错了自行百度即可,操作起来不麻烦的)

注意time.sleep()是必要的,一是为了避免频繁操作被浏览器提醒,二是在网络不好的情况下让网页加载完全,否则都会导致报错

一定不要图快,目前我是8s左右完成一次检索和数据录入,老师给我的要求是700次左右,也就运行个一个半个小时

这之中还会遇到诸多问题,在代码的注释里也都写到了

函数模块介绍

创建模拟浏览器对象

# 返回虚拟浏览器对象
def openUrl(url):driver = webdriver.Chrome()driver.get(url)time.sleep(3)return driver

只需要执行一次的部分

xpath如何获取百度一下即可

# 只运行一次,避免重复操作影响效率
def onceClick(driver):#选择报纸栏driver.find_element_by_xpath('/html/body/div[3]/div[1]/div/ul[1]/li[4]/a').click()time.sleep(2)#点击包含非学术文献driver.find_element_by_xpath('/html/body/div[2]/div/div[2]/div/div[1]/div[1]/div[2]/div[1]/div[1]/label/input').click()time.sleep(1)#更改为全文模式driver.find_element_by_xpath('//*[@id="gradetxt"]/dd[1]/div[2]/div[1]').click()time.sleep(2)driver.find_element_by_xpath('//*[@id="gradetxt"]/dd[1]/div[2]/div[1]/div[2]/ul/li[5]').click()time.sleep(2)

需要批量执行的重复操作部分

这部分主要是知网页面的交互产生的问题,反复改了好几次终于解决了

第一次检索的时候发表年度页面是关着的
在这里插入图片描述
第二次又变成了不关,但是如果要获取更多需要点击最下面的键,因此引入了flag(结合主函数看)
在这里插入图片描述
try-except是为了防止年份数量不足而报错,因为有些关键词出现得很少,就不需要点击上图这个键,如果不try掉就会报错终止运行

# 输入关键词并点击,循环操作
def send_and_click(driver,kw,np,flag): #输入主题词driver.find_element_by_xpath('//*[@id="gradetxt"]/dd[1]/div[2]/input').send_keys(kw)time.sleep(0.5)#输入报纸名字driver.find_element_by_xpath('//*[@id="gradetxt"]/dd[3]/div[2]/input').send_keys(np)time.sleep(0.5)#点击检索driver.find_element_by_xpath('/html/body/div[2]/div/div[2]/div/div[1]/div[1]/div[2]/div[2]/input').click()time.sleep(1.5)if flag==True:#第一次检索时需要展开发表年度大标题driver.find_element_by_xpath('//*[@id="divGroup"]/dl[3]/dt').click()time.sleep(2)if flag==False:#第二次开始,发表年度仅缩小,没有收回到大标题,所以展开发表年度缩小的页面,#使用try-except是为了防止年份数量不足而报错,影响程序进行try:driver.find_element_by_xpath('//*[@id="divGroup"]/dl[3]/dd/div/a').click()time.sleep(1)except:pass#打开被缩小的检索页driver.find_element_by_xpath('/html/body/div[2]/div/div[2]/div/div[2]/a[2]').click()time.sleep(0.5)#清空原有内容driver.find_element_by_xpath('//*[@id="gradetxt"]/dd[1]/div[2]/input').clear()driver.find_element_by_xpath('//*[@id="gradetxt"]/dd[3]/div[2]/input').clear()time.sleep(1)

获取网页数据

这个部分主要还是根据自己的需求来,这边我是返回列表

# 获取内容并返回数量列表
def getData_and_print(driver,tw,dp):cntDict={}for index in range(1,13):try:text1=driver.find_element_by_xpath('//*[@id="divGroup"]/dl[3]/dd/div/ul/li['+str(index)+']').textcntDict[text1[:4]]=text1[5:-1]except:continue       for i in years:if i not in cntDict.keys():cntDict[i]='0'       cnttuplelist=[]cntlist=[]for i in sorted (cntDict,reverse=False): if int(i)>=2011 and int(i)<=2018:cnttuplelist.append((i, cntDict[i]))cntlist.append(cntDict[i])     else:continuefor ct1,ct2 in cnttuplelist:print(dp+'\t\t\t'+ct1+'\t'+tw+'\t\t'+ct2)      return cntlist 

录入excel

这个部分也是根据自己的需求来,主要是找准数据的录入规则

#加载并将数据写入excel指定位置
def load_into_excel(datalist,indexi,indexj):wb=openpyxl.load_workbook('data.xlsx')ws=wb['Sheet1']for i in range(len(datalist)):ws.cell(row=i+8*indexi+2,column=4+indexj).value=datalist[i]   wb.save("data.xlsx")

主函数

#主函数
if __name__ =='__main__':driver=openUrl('https://kns.cnki.net/kns8/AdvSearch?dbprefix=CFLS&&crossDbcodes=CJFQ%2CCDMD%2CCIPD%2CCCND%2CCISD%2CSNAD%2CBDZK%2CCCJD%2CCCVD%2CCJFN')onceClick(driver)flag=Truefor indexi,dp in enumerate(dailyPapers):#报纸为行for indexj,tw in enumerate(topicWords):#关键词为列send_and_click(driver,tw,dp,flag)flag=False #运行第一次后,标记flag为Falsecntlist=getData_and_print(driver,tw,dp)load_into_excel(cntlist,indexi,indexj)driver.close()

本地文件结构

只需要将data.xlsx和代码文件放一起即可,或者用绝对路径也可
在这里插入图片描述

data.xlsx要求标题等事先按自己的要求准备好,代码只输入数据

在这里插入图片描述

全部代码

from selenium import webdriver 
import time 
import openpyxl
#自定义内容
topicWords=['深化改革','中国梦','放管服']
dailyPapers=['北京日报','天津日报']
years='2022','2021','2020','2019','2018','2017','2016','2015','2014','2013','2012','2011']# 返回虚拟浏览器对象
def openUrl(url):driver = webdriver.Chrome()driver.get(url)time.sleep(3)return driver# 只运行一次,避免重复操作影响效率
def onceClick(driver):#选择报纸栏driver.find_element_by_xpath('/html/body/div[3]/div[1]/div/ul[1]/li[4]/a').click()time.sleep(2)#点击包含非学术文献driver.find_element_by_xpath('/html/body/div[2]/div/div[2]/div/div[1]/div[1]/div[2]/div[1]/div[1]/label/input').click()time.sleep(1)#更改为全文模式driver.find_element_by_xpath('//*[@id="gradetxt"]/dd[1]/div[2]/div[1]').click()time.sleep(2)driver.find_element_by_xpath('//*[@id="gradetxt"]/dd[1]/div[2]/div[1]/div[2]/ul/li[5]').click()time.sleep(2)# 输入关键词并点击,循环操作
def send_and_click(driver,kw,np,flag): #输入主题词driver.find_element_by_xpath('//*[@id="gradetxt"]/dd[1]/div[2]/input').send_keys(kw)time.sleep(0.5)#输入报纸名字driver.find_element_by_xpath('//*[@id="gradetxt"]/dd[3]/div[2]/input').send_keys(np)time.sleep(0.5)#点击检索driver.find_element_by_xpath('/html/body/div[2]/div/div[2]/div/div[1]/div[1]/div[2]/div[2]/input').click()time.sleep(1.5)if flag==True:#第一次检索时需要展开发表年度大标题driver.find_element_by_xpath('//*[@id="divGroup"]/dl[3]/dt').click()time.sleep(2)if flag==False:#第二次开始,发表年度仅缩小,没有收回到大标题,所以展开发表年度缩小的页面,#使用try-except是为了防止年份数量不足而报错,影响程序进行try:driver.find_element_by_xpath('//*[@id="divGroup"]/dl[3]/dd/div/a').click()time.sleep(1)except:pass#打开被缩小的检索页driver.find_element_by_xpath('/html/body/div[2]/div/div[2]/div/div[2]/a[2]').click()time.sleep(0.5)#清空原有内容driver.find_element_by_xpath('//*[@id="gradetxt"]/dd[1]/div[2]/input').clear()driver.find_element_by_xpath('//*[@id="gradetxt"]/dd[3]/div[2]/input').clear()time.sleep(1)# 获取内容并返回数量列表
def getData_and_print(driver,tw,dp):cntDict={}for index in range(1,13):try:text1=driver.find_element_by_xpath('//*[@id="divGroup"]/dl[3]/dd/div/ul/li['+str(index)+']').textcntDict[text1[:4]]=text1[5:-1]except:continue       for i in years:if i not in cntDict.keys():cntDict[i]='0'       cnttuplelist=[]cntlist=[]for i in sorted (cntDict,reverse=False): if int(i)>=2011 and int(i)<=2018:cnttuplelist.append((i, cntDict[i]))cntlist.append(cntDict[i])     else:continuefor ct1,ct2 in cnttuplelist:print(dp+'\t\t\t'+ct1+'\t'+tw+'\t\t'+ct2)      return cntlist #加载并将数据写入excel指定位置
def load_into_excel(datalist,indexi,indexj):wb=openpyxl.load_workbook('data.xlsx')ws=wb['Sheet1']for i in range(len(datalist)):ws.cell(row=i+8*indexi+2,column=4+indexj).value=datalist[i]   wb.save("data.xlsx")#主函数
if __name__ =='__main__':driver=openUrl('https://kns.cnki.net/kns8/AdvSearch?dbprefix=CFLS&&crossDbcodes=CJFQ%2CCDMD%2CCIPD%2CCCND%2CCISD%2CSNAD%2CBDZK%2CCCJD%2CCCVD%2CCJFN')onceClick(driver)flag=Truefor indexi,dp in enumerate(dailyPapers):#报纸为行for indexj,tw in enumerate(topicWords):#关键词为列send_and_click(driver,tw,dp,flag)flag=False #运行第一次后,标记flag为Falsecntlist=getData_and_print(driver,tw,dp)load_into_excel(cntlist,indexi,indexj)driver.close()

结果预览

控制台

在这里插入图片描述

文件

在这里插入图片描述


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部