学妹需要查询一批文献的引证文献数据,采集指定文章的引证文献数据
采集思路学妹提供的数据为题名+作者。
在高级检索界面输入主题及作者,拿到文章链接以及引证文献列表链接。为避免被参数困扰,数量不多的情况就直接使用selenium。若出现多条返回结果,则可以在筛选框筛选出显示50条及按相关度排序,这样基本上在第一页就可以拿到相应数据,无需翻页。
拿到引证文献列表链接后开始采集每篇引证文献的链接。期刊、博士等每个类目下都有分页,每页10条。此时selenium最为简单方便。
具体思路如下:
先解析出期刊等每个类目的标签(‘div[@class=“essayBox”]’);
再遍历每个essayBox标签,解析出数量;
若数量小于10条,直接解析即可;
若大于10条,先解析再翻页,直到翻到最后一页。
拿到引证文献的链接,就可以愉快的采集相应文献的数据了!
引入相关包
# -*- coding: utf_8 -*- import os import time import random import pandas as pd from lxml import etree from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Options
设置远程调试
options = Options() options.debugger_address = "127.0.0.1:9299" browser = webdriver.Chrome(chrome_options=options)
手动启动浏览器
CMD: 浏览器路径 + --remote-debugging-port=9299
def get_data_list(essayBox_index):
"""
:param essayBox_index: 分类标签的索引
:return: 当前标签下所有文献标题及链接
"""
data_list = []
res = browser.page_source
xpath_str = f'//div[@id="divResult"]/div[@][{essayBox_index}]'
info = etree.HTML(res)
data_list_info = info.xpath(xpath_str)[0]
data_list_1 = [f"https://kns.cnki.net{i}" for i in data_list_info.xpath('./ul/li/a/@href')]
data_list_2 = [i.strip() for i in data_list_info.xpath('./ul/li/a//text()')]
for k, v in dict(zip(data_list_1, data_list_2)).items():
dict_ = {'yw_title': v, 'yw_link': k}
data_list.append(dict_)
return data_list
def get_page_info(essayBox_index):
"""
:param essayBox_index: 分类标签的索引
:return: 当前标签下页码信息
"""
res = browser.page_source
xpath_str = f'//div[@id="divResult"]/div[@][{essayBox_index}]/div[@]//text()'
info = etree.HTML(res)
page_info = ''.join([i.strip() for i in info.xpath(xpath_str) if i.strip() != ''])
return page_info
def click_next_page(essayBox_index):
"""
:param essayBox_index: 分类标签的索引
:return: 点击当前标签内下一页
"""
next_page = browser.find_elements(By.XPATH, f'//div[@][{essayBox_index}]//div[@]/span[1]/a')[-2]
print('next_page: ', next_page)
browser.execute_script("$(arguments[0]).click()", next_page)
def run(FileName, quote_link):
print('正在采集:', FileName)
browser.get(quote_link)
time.sleep(random.randint(3, 5)) # 加载较慢,这里一定要等待2秒左右,保险起见我等待3-5秒
res = browser.page_source
info = etree.HTML(res)
essayBox_labels = info.xpath('//div[@id="divResult"]/div[@]') # 获取每个文献分类标签
data_list_all = []
for essayBox_label in essayBox_labels:
data_type = ''.join([i.strip() for i in essayBox_label.xpath('./div[@]/text()') if i.strip() != ''])
data_num = int(''.join([i.strip() for i in essayBox_label.xpath('./div[@]//span[@name="pcount"]/text()') if i.strip() != ''])) # 该分类下文献的数量
essayBox_index = essayBox_labels.index(essayBox_label) + 1 # 该分类标签索引,xpath里面从1开始所以+1
if data_num <= 10: # 文献数量<=10无需翻页,直接解析即可
print(essayBox_label, data_type, data_num)
data_list = get_data_list(essayBox_index=essayBox_index)
for ij in data_list:
ij.update({'data_type': data_type, 'data_num': data_num})
ij.update(item_1)
print(ij)
data_list_all.append(ij)
else: # 文献数量>10,在while True里面循环 解析+翻页
print(essayBox_label, data_type, data_num)
while True:
data_list = get_data_list(essayBox_index=essayBox_index) # 解析文献名称及链接
for ij in data_list:
ij.update({'data_type': data_type, 'data_num': data_num})
ij.update(item_1)
print(ij)
data_list_all.append(ij)
page_info = get_page_info(essayBox_index=essayBox_index) # 获取当前页码标签内是否有下一页
if '下一页' in page_info:
click_next_page(essayBox_index=essayBox_index) # 如果有下一页就点击
else:
break
time.sleep(random.randint(2, 3))
# 懒得入数据库,直接保存在本地,每条数据一个文件,全部采集完成后pd.concat直接合并即可
file_path = f"./rd_3/{FileName}.xlsx"
df_2 = pd.Dataframe(data_list_all)
df_2.to_excel(file_path, index=False)
print('文件保存成功:', file_path)
time.sleep(random.randint(2, 3))
if __name__ == '__main__':
# 读取文件
df_1 = pd.read_excel('./20211210.xlsx')
list_1 = df_1.to_dict(orient='records')
list_jd = [i.replace('.xlsx', '') for i in os.listdir('./rd_3')]
# 文件我是保存在本地rd_3文件夹下面的,跑之前读一遍已经采集的FileName
for item_1 in list_1:
FileName = item_1['FileName']
quote_link = item_1['引用链接']
if FileName in list_jd:
print('文件已采集:', FileName)
pass
else:
if quote_link == quote_link:
run(FileName=FileName, quote_link=quote_link)
运行结果:
以上代码为翻页采集列表,至于采集引用链接及文献详情就不再赘述。



