python爬取百度学术文章获取免费下载地址
python爬取百度学术文章获取免费下载地址
学了一段时间的爬虫,给自己找一个小项目来练练手,爬取百度百科文章。根据关键字搜索相关文献,爬取指定页数的文献列表,对于每篇文献的详细页面再进一步分析,获取免费下载地址。
程序版本:python3.7
好了,废话不多说,开始进入正题。
1. 爬取百度学术文章
首先,我们打开百度学术首页:http://xueshu.baidu.com/
在这里输入关键词进行搜索,我们以“深度学习”为例,进行搜索。
这里是网页具体网址,暂时我们看不出来规律,待会我们点击翻页对比进行观察。
搜索后的网页显示如下:
在此我们我们主要关注文献题目,摘要,作者,以及隐藏的文献详细地址。F12(谷歌浏览器)审查元素。
利用Beautifulsoup进行页面分析,将这些内容提取出来。
#对于每页的文献信息(每页基本包含10篇文献),提取所有的文献主题、作者、摘要、文献详细地址
def get_urls(text):
all_titles = []#主题
all_abstracts = []#摘要
all_authors = []#作者
all_paper_urls = []#论文初步网址
soup = BeautifulSoup(text,'lxml')
title_datas = soup.select('div.sc_content > h3 > a')#select返回值类型为<class 'list'>
author_datas = soup.find_all('div','sc_info')#find_all返回值类型为<class 'bs4.element.ResultSet'>
abstract_datas = soup.find_all('div','c_abstract')
for item in title_datas:
result = {
'title':item.get_text(),
'href':item.get('href')#关于论文的详细网址,经过观察发现需要提取部分内容
#http://xueshu.baidu.com/usercenter/paper/show?paperid=389ef371e5dae36e3a05b187f7eb2a95&site=xueshu_se
#/s?wd=paperuri%3A%28389ef371e5dae36e3a05b187f7eb2a95%29&filter=sc_long_sign&sc_ks_para=q%3D%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%E7%A0%94%E7%A9%B6%E7%BB%BC%E8%BF%B0&sc_us=11073893925633194305&tn=SE_baiduxueshu_c1gjeupa&ie=utf-8
}
all_titles.append(item.get_text())
wd = str(parse.urlparse(item.get('href')).query).split('&')[0]
paperid = wd.split('%')[2][2:]
params = {
'paperid': paperid,
'site': 'xueshu_se'
}
url = 'http://xueshu.baidu.com/usercenter/paper/show?' + urlencode(params)
all_paper_urls.append(url)
# print(url)
# print(result)
for abs in abstract_datas:#abs类型是<class 'bs4.element.Tag'>
str_list = []
for l in abs.contents:#l的类型是<class 'bs4.element.NavigableString'>
str_list.append(str(l).replace('\n','').strip())
# print("".join(str_list).replace('<em>','').replace('</em>',''))
all_abstracts.append("".join(str_list).replace('<em>','').replace('</em>',''))
for authors in author_datas:#authors类型为<class 'bs4.element.Tag'>
for span in authors.find_all('span',limit=1):#此时span类型为<class 'bs4.element.Tag'>
each_authors = []
for alist in span.find_all('a'):
each_authors.append(alist.string)
all_authors.append(each_authors)
return all_titles,all_authors,all_abstracts,all_paper_urls
其中文献详细地址取值之后,需要进行简单的处理。比如说《深度学习研究综述》这篇文章,爬取的html中文献地址与实际打开的url不是完全相同,我们对比一下。
接下来,我们要分析翻页功能,点击下一页,对比网址区别。
第一页:
http://xueshu.baidu.com/s?wd=深度学习&pn=0&tn=SE_baiduxueshu_c1gjeupa&ie=utf-8&sc_f_para=sc_tasktype%3D{firstSimpleSearch}&sc_hit=1
第二页:
http://xueshu.baidu.com/s?wd=深度学习&pn=10&tn=SE_baiduxueshu_c1gjeupa&ie=utf-8&sc_f_para=sc_tasktype%3D{firstSimpleSearch}&sc_hit=1
第三页:
http://xueshu.baidu.com/s?wd=深度学习&pn=20&tn=SE_baiduxueshu_c1gjeupa&ie=utf-8&sc_f_para=sc_tasktype%3D{firstSimpleSearch}&sc_hit=1
可以发现,主要是pn的值在发生变化,每页只显示10篇文章,这样我们就可以在程序里控制分页了。
def get_page(keywords,offset):
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36'
}
params = {
'wd': keywords,
'pn':offset,
'tn':'SE_baiduxueshu_c1gjeupa',
'ie':'utf-8',
'sc_hit':'1'
}
url = "http://xueshu.baidu.com/s?"+urlencode(params)
try:
response = requests.get(url,headers=headers)
if response.status_code == 200:
return response.text
except requests.ConnectionError:
return None
至此,我们可以取到文献题目,摘要,作者,以及文献详细地址等信息。如果对文本分析感兴趣的话,可以参考@
llh_1178的文章/爬取百度学术文章及文本挖掘分析
2. 文献详细页面分析
我们以《深度学习研究综述》文章为例,跳转到详细页面。
获取当前页面免费下载栏处免费下载的网址,这里使用正则表达式进行匹配。
#对于每个文献页面爬取的详细页面内容进行提取,找出所有可免费下载的地址
def get_download_urls(text):
download_urls = []
# pattern = re.compile('<div.*?id="savelink_wr".*?<a.*?class="dl_item".*?href="(.*?).*?<span.*?class="dl_lib".*?>(.*?)</span>.*?</div>',re.S)
pattern = re.compile('<a.*?class="dl_item".*?href="(.*?)".*?<span.*?class="dl_lib">(.*?)</span>',re.S)
results = re.findall(pattern,text)
for item in results:
each_data = {
'url':item[0],
'download':item[1]
}
if "免费" in each_data.get('download'):
download_urls.append(each_data.get('url'))
# print(each_data)
return download_urls
至此,我们已经得到想要的下载地址。最后将爬取到的所有内容存入到Json文件中。main方法如下:
keywords = str(input("请输入在百度学术网站需要查询的关键词:\n"))
print("开始爬取百度学术网站关于“{}”关键词的相关内容".format(keywords))
for i in range(1):
print("开始爬取第{}页的内容".format(str(i+1)))
offset = i * 10
text = get_page(keywords,offset)
all_titles, all_authors, all_abstracts,all_paper_urls = get_urls(text)
all_dlUrls = []
for k in range(len(all_paper_urls)):
new_text = get_download(all_paper_urls[k])
download_urls = get_download_urls(new_text)
all_dlUrls.append(download_urls)
papers = set_paper(all_titles, all_authors, all_abstracts,all_dlUrls)
save_data(papers)
print("保存成功!")
详细代码:https://github.com/Acorn2/PythonSpider/blob/master/cdsn_learn01/literature_spider.py