Python爬虫内容都是于2019上半年写的,关于某些网站的爬取技巧可能已经过时了,仅供参考。
前言
记得当初自己写毕业论文的时候,需要在网上查找大量的文献资料,虽然主要是在知网上查阅,但是也是会其它学术网站进行搜索。这样一来,文献搜索工作量就变得比较大,再加之并不是每篇文献都可以免费下载,所以写毕业论文需要花费的时间和精力都比较大。当时自己不懂爬虫这门技术,只能白费气力在网上查找。刚好今年女朋友也需要写毕业论文,我就自告奋勇说替她查找相关文献资料,帮助她完成毕业论文。
本次的任务是爬取百度百科文章,根据关键字搜索相关文献,爬取指定页数的文献列表,对于每篇文献的详细页面再进一步分析,获取免费下载地址。
程序版本:python3.7
好了,废话不多说,开始进入正题。
爬取百度学术文章
首先,我们打开百度学术首页: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返回值类型为
author_datas = soup.find_all('div','sc_info')#find_all返回值类型为
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类型是
str_list = []
for l in abs.contents:#l的类型是
str_list.append(str(l).replace('\n','').strip())
# print("".join(str_list).replace('','').replace('',''))
all_abstracts.append("".join(str_list).replace('','').replace('',''))
for authors in author_datas:#authors类型为
for span in authors.find_all('span',limit=1):#此时span类型为
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 不是完全相同,我们对比一下。
接下来,我们要分析翻页功能,点击下一页,对比网址区别。
可以发现,主要是 pn 的值在发生变化,每页只显示 10 篇文章,这样我们就可以在程序里控制分页了。
第一页:
http://xueshu.baidu.com/s?wd=%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0&pn=0&tn=SE_baiduxueshu_c1gjeupa&ie=utf-8&sc_f_para=sc_tasktype%3D%7BfirstSimpleSearch%7D&sc_hit=1
第二页:
http://xueshu.baidu.com/s?wd=%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0&pn=10&tn=SE_baiduxueshu_c1gjeupa&ie=utf-8&sc_f_para=sc_tasktype%3D%7BfirstSimpleSearch%7D&sc_hit=1
第三页:
http://xueshu.baidu.com/s?wd=%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0&pn=20&tn=SE_baiduxueshu_c1gjeupa&ie=utf-8&sc_f_para=sc_tasktype%3D%7BfirstSimpleSearch%7D&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的文章爬取百度学术文章及文本挖掘分析
文献详细页面分析
我们以《深度学习研究综述》文章为例,跳转到详细页面。
获取当前页面免费下载栏处免费下载的网址,这里使用正则表达式进行匹配。
#对于每个文献页面爬取的详细页面内容进行提取,找出所有可免费下载的地址
def get_download_urls(text):
download_urls = []
# pattern = re.compile('(.*?) .*?
pattern = re.compile('
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