import requests
import time
from selenium import webdriver
from bs4 import BeautifulSoup
#定义搜索函数并总结文献关键信息
def search():
#driver =webdriver.Chrome()
final_url_list=[]
Boolean_dict={'1':'AND','2':'OR','3':'NOT'}
span_dict={'1':1,'2':5,'3':10}
params={'term':'',
'timeline':'expanded'}
headers = {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
}
# 输入关键词1和关键词2和布尔逻辑(大写AND,OR,NOT)
keyword1 = input('请输入搜索关键词1:n')
Boolean_Logic=input('请输入两个关键词之间的布尔逻辑序号:1.AND,2.OR,3.NOT,4.无(只有一个关键词):n')
#无布尔逻辑连接词,只搜索一个关键词
if Boolean_Logic == '4':
span = input('请输入查询文献的年限:1.最近1年,2.最近5年,3.最近10年,4.自定义,5.无限制:n')
#只有一个关键词且无时间限制
if span == '5':
url ='https://pubmed.ncbi.nlm.nih.gov/?term={}'.format(keyword1)
params['term']=keyword1
#params['filter']=''
#只有一个关键词且是自定义时间
elif span =='4':
start_time=input('请输入开始年份:')
end_time=input('请输入结束年份:')
url ='https://pubmed.ncbi.nlm.nih.gov/?term={}&filter=dates.{}-{}'.format(keyword1,start_time,end_time)
params['term']=keyword1
params['filter']='dates.{}-{}'.format(start_time,end_time)
#只有一个关键词且时间为常用时间
else:
url = url ='https://pubmed.ncbi.nlm.nih.gov/?term={}&filter=datesearch.y_{}'.format(keyword1,span_dict[span])
params['term']=keyword1
params['filter']='datesearch.y_{}'.format(span_dict[span])
#有布尔逻辑词,搜索两个关键词
else:
keyword2 = input('请输入搜索关键词2:n')
span = input('请输入查询文献的年限:1.最近1年,2.最近5年,3.最近10年,4.自定义,5.无限制:n')
#两个关键词且无时间限制
if span == '5':
url ='https://pubmed.ncbi.nlm.nih.gov/?term={}+{}+{}'.format(keyword1,Boolean_dict[Boolean_Logic],keyword2)
params['term']='({}) {} ({})'.format(keyword1,Boolean_dict[Boolean_Logic],keyword2)
#params['filter']=''
#两个关键词且自定义时间
elif span =='4':
start_time=input('请输入开始年份:')
end_time=input('请输入结束年份:')
url ='https://pubmed.ncbi.nlm.nih.gov/?term={}+{}+{}&filter=dates.{}-{}'.format(keyword1,Boolean_dict[Boolean_Logic],keyword2,start_time,end_time)
params['term']=keyword1
params['filter']='dates.{}-{}'.format(start_time,end_time)
#两个关键词且为常用时间
else:
url ='https://pubmed.ncbi.nlm.nih.gov/?term={}+{}+{}&filter=datesearch.y_{}'.format(keyword1,Boolean_dict[Boolean_Logic],keyword2,span_dict[span])
params['term']='({}) {} ({})'.format(keyword1,Boolean_dict[Boolean_Logic],keyword2)
params['filter']='datesearch.y_{}'.format(span_dict[span])
#第一个函数第二大部分
head=['标题','作者','发表年份','引用杂志']
final_result_dict={}
result_dicts1={}
result_dicts2={}
document_url_list=[]
res=requests.get(url,headers=headers,params=params)
bs=BeautifulSoup(res.text,'html.parser')
page_info=bs.find('label',class_='of-total-pages')
#所查找文献的最大数量
docu_max=bs.find('div',class_='results-amount').find('span',class_='value').text
page_max=int(input('该检索式的文献共有{}页,共有{}篇,请选择下载文献的最大页数(每一页默认最多10篇):n'.format(page_info.text[3:],docu_max)))
for page_num in range(1,page_max+1):
final_url = url + '&page={}'.format(page_num)
params['page']=str(page_num)
final_url_list.append(final_url)
#print(final_url_list)
index=1
num=1
index_not_done=1
#print(final_url_list)
for final_urles in final_url_list:
#print(final_urles)
document_res=requests.get(final_urles,headers=headers)
document_bs=BeautifulSoup(document_res.text,'html.parser')
document_info = document_bs.find_all('div',class_='docsum-content')
#创造“标题,杂志,分数,分区,发表年限”的字典
#先创造一个空列表,等下用来装每篇文献的具体链接
for document_content in document_info:
document_url ='https://pubmed.ncbi.nlm.nih.gov/'+document_content.find('a', class_="docsum-title")['href']
#print(document_url)
#解读每一篇文献的具体结构
document_url_res=requests.get(document_url,headers=headers)
document_url_bs=BeautifulSoup(document_url_res.text,'html.parser')
#print(document_url)
#print(num)
#num+=1
document_url_list.append(document_url)
#print(document_url_list)
#少部分文献不存在DOI,若存在,则按照正常思路下载
if document_url_bs.find('span', class_="identifier doi")!=None:
result_dict={}
document_DOI=document_url_bs.find('span', class_="identifier doi").find('a', class_="id-link").text
document_href=document_url_bs.find('span', class_="identifier doi").find('a', class_="id-link")['href']
document_title=document_url_bs.find('h1', class_="heading-title").text
document_Author=document_content.find('span', class_="docsum-authors full-authors").text
document_year=document_content.find('span', class_="docsum-journal-citation short-journal-citation").text[-5:-1]
document_cite=document_content.find('span', class_="docsum-journal-citation short-journal-citation").text[:-7]
result_dict['DOI']=document_DOI.strip()
print(result_dict['DOI'])
print('拥有DOI的文献篇数:{}'.format(index))
result_dict['标题']=document_title.strip()
result_dict['手动下载链接']=document_href.strip()
result_dict['作者']=document_Author
result_dict['发表年份']=document_year
result_dict['引用杂志']=document_cite
result_dicts1[index]=result_dict
index+=1
#若不存在,则列出此类文献的信息并跳过
else:
result_dict2={}
total_row=[]
#document_href=document_url_bs.find('span', class_="identifier doi").find('a', class_="id-link")['href']
document_title=document_url_bs.find('h1', class_="heading-title").text
document_Author=document_content.find('span', class_="docsum-authors full-authors").text
document_year=document_content.find('span', class_="docsum-journal-citation short-journal-citation").text[-5:-1]
document_cite=document_content.find('span', class_="docsum-journal-citation short-journal-citation").text[:-7]
result_dict2['标题']=document_title.strip()
result_dict2['手动下载链接']=document_url
result_dict2['作者']=document_Author
result_dict2['发表年份']=document_year
result_dict2['引用杂志']=document_cite
head=['标题','手动下载链接','作者','发表年份','引用杂志']
result_dicts2[index_not_done]=result_dict2
print('result_dicts2的值为{}'.format(result_dicts2.values()))
for value in result_dicts2.values():
total_row.append(list(value.values()))
with open('D:/文献/此次下载文献/此次未找到DOI文献目录.csv','w+',encoding='utf-8',newline='') as f:
f_csv = csv.DictWriter(f, fieldnames=head)
f_csv.writeheader()
csv_writer = csv.writer(f)
csv_writer.writerows(total_row)
print('total_row的内容为{}'.format(total_row))
print('文献{}无法查找DOI,请前往{}手动查询'.format(document_title.strip(),document_url))
print('未找到DOI的篇数{}'.format(index_not_done))
index_not_done+=1
continue
final_result_dict['DOI']= result_dicts1
final_result_dict['NOT DOI']= result_dicts2
#print(result_list)
return final_result_dict
#创建第二个函数以保存文献的大概信息
import os
import csv
from openpyxl import Workbook
def info(final_result_dict):
#创建数据表格
path = 'D:/文献/此次下载文献/'
# 判断是否存在文件夹',若不存在,则新建
if not os.path.exists(path):
os.mkdir(path)
total_row = []
for value in final_result_dict['DOI'].values():
total_row.append(list(value.values()))
#以不需要保存的形式创建总下载目录
headers=['标题','DOI','手动下载链接','作者','发表年份','引用杂志']
with open(path+'此次文献下载目录.csv','w',encoding='utf-8',newline='') as f:
f_csv = csv.DictWriter(f, fieldnames=headers)
f_csv.writeheader()
csv_writer = csv.writer(f)
csv_writer.writerows(total_row)
return final_result_dict
#print(search())
from bs4 import BeautifulSoup
import requests
pdf_r = requests.get('https://sci-hub.se/10.1055/s-0039-1695768')
bs=BeautifulSoup(pdf_r.text,'html.parser')
pdf_info=bs.find_all('embed')
def download(final_result_dict):
#print(result_dicts)
num_done=1
num_not_done=1
num_not_download=1
for item in final_result_dict['DOI'].values():
#print(item['DOI'])
# 拼接完整 url
url = 'https://sci-hub.se/' + item['DOI']
print('{}n'.format(url))
pdf_r = requests.get(url)
#print(pdf_r)
bs=BeautifulSoup(pdf_r.text,'html.parser')
#print(bs)
#有时候会莫名其妙出现找不到head的情况,这里加上判断head是否存在的判断
if bs.find('head')!=None:
bs_head=bs.find('head').find('title').text
#检查文献是否可以用sci-hub下载,能则继续,不能则跳过,并指出有哪些文献
#不能
if bs_head == 'Sci-Hub: article not found' or bs_head=='Sci-Hub: 未找到文章':
print('文献{}不能自动下载,请前往手动下载链接{}n'.format(item['标题'],item['手动下载链接']))
headers=['DOI','标题','手动下载链接','作者','发表年份','引用杂志']
total_row=[]
for value in final_result_dict['NOT DOI'].values():
total_row.append(list(value.values()))
with open('D:/文献/此次下载文献/此次需手动下载文献目录.csv','w+',encoding='utf-8',newline='') as f:
f_csv = csv.DictWriter(f, fieldnames=headers)
f_csv.writeheader()
csv_writer = csv.writer(f)
csv_writer.writerows(total_row)
print('需手动下载篇数:{}'.format(num_not_done))
num_not_done+=1
continue
#能
else:
total_row=[]
if bs.find('embed',id='pdf')!=None:
pdf_info=bs.find('embed',id='pdf')['src']
pdf_url='https://sci-hub.se'+pdf_info
print('{}n'.format(pdf_url))
pdf_url_r=requests.get(pdf_url)
print('文献{}下载成功,链接为{}'.format(item['标题'],pdf_url))
#文件命名不能出现一下字符:、/、:、*、?、"、<、>、| replace('','').replace('/','').replace(':','').replace('*','').replace('?','').replace('"','').replace('<','').replace('>','').replace('| ','')
pdf_title=item['标题'].replace("''","").replace("/","").replace(':','').replace('*','').replace('?','').replace('"','').replace('<','').replace("-","").replace('>','').replace('| ','')
with open('D:/文献/此次下载文献/{}.pdf'.format(pdf_title), 'wb') as f:
f.write(pdf_url_r.content)
print('文献{}已下载完成'.format(item['标题']))
print('完成下载篇数:{}'.format(num_done))
num_done+=1
elif bs.find('embed',id='pdf') ==None:
head=['DOI','标题','手动下载链接','作者','发表年份','引用杂志']
print('文献{}由于未知原因下载失败,请前往链接{}查看'.format(item['标题'],item['手动下载链接']))
print('因未知原因下载失败文献数量:{}'.format(num_not_download))
num_not_download+=1
total_row.append(item['DOI'])
total_row.append(item['标题'])
total_row.append(item['手动下载链接'])
total_row.append(item['作者'])
total_row.append(item['发表年份'])
total_row.append(item['引用杂志'])
with open('D:/文献/此次下载文献/此次因未知原因需手动下载文献目录.csv','w+',encoding='utf-8',newline='') as f:
f_csv = csv.DictWriter(f, fieldnames=head)
f_csv.writeheader()
csv_writer = csv.writer(f)
csv_writer.writerows(total_row)
continue
print(download(info(search())))
以上就是我的代码和运行结果(关键词可改变),目前有两个问题,1.最核心的问题:我用多个浏览器确认了236行(bs.find('embed',id='pdf'))的条件判断语句里的标签是存在的,但不知为何,今天下午使用代码,全部爬到的文献资源全都走了bs.find('embed',id='pdf')==None(也就是最下面的else)路线,我真的百思不得其解。希望各位大神能够提出解决方法,如能顺利解决,我将会改良后的代码发给你(如果你需要的话)。2.最后的else分支打印出来的CSV文件内容不对,都是一格一个字母,如果可以希望大神们也给出解决方法,同样的,如果你需要,改良后代码无偿分享。谢谢!



