如何⽤python抓取⽂献_基于Python对知⽹(CNKI)主题⽂献
爬⾍
本⽂介绍使⽤Python爬⾍技术快速获取知⽹1000多篇某个主题的⽂章的题⽬,作者,作者单位,引⽤次数,下载次数,发表刊物,发表时间,以及⽂章摘要。
学习爬⾍开始,我就想着对CNKI主题⽂献进⾏爬⾍,对感兴趣的主题⽂章进⾏抓取,获取相关⽂章的基本信息和摘要,⽅便快速了解某⼀个领域的研究进程,重点等等。
经过不断的修改,终于完成此⽬的。
在此爬⾍程序编写过程,需要注意⼏个问题。
1. 选择合适的⽹站⼊⼝;
⼀般我们进⼊知⽹是,wwwki,我发现对此⽹站进⾏爬取,难以获取完整的⽹站源码,最后发现 searchki/ 能得到完整源码。
2. 分析⽹站URL:
将图中的URL复制出来,得到下⾯的URL:searchki/search.aspx?
q=%E7%B2%BE%E5%87%86%E6%89%B6%E8%B4%AB&rank=citeNumber&cluster=all&val=&p=0发现被编码了,需要对复制出来的URL使⽤ urllib.unquote() 解码。
分析解码后的URL:searchki/search.aspx?q=精准扶贫&rank=citeNumber&cluster=all&val=CJFDTOTAL&p=0 ;通过选择不同的排序,不同的搜索关键词,以及不同的⽂献类型,可以确定 'q='字段控制搜索的关键词,'rank=' 控制排序⽅式,“p=” 字段控制了翻页, 并且步长为15。 最终确定搜索URL为:url='searchki/search.aspx?
q='+str(keywords)+'&rank=citeNumber&cluster=all&val=CJFDTOTAL&p='+'number'。
3. 转码问题:
在爬取⽹页过程中,发现得到的⽹页源码打印出来后,是乱码,最终发现是因为⽹页源码的编码⽅式并不是UTF-8,因此,为了得到可以⽤于解析的的⽹页源码,需要对⽹页源码进⾏转码,⾸先从原始编码⽅式转化为通⽤型的Unicode,然后再转码为:UTF-8, 转码⽅式:
(test,headers=headers) # 获得⽹页源码
ding).decode('utf-8') # 转码成可以分析的编码
4. 代理IP问题:
在爬⾍过程中,爬取少量⽹页和爬取⼤量⽹页存在较⼤区别。爬取较少⽹页是,被爬的服务器不会拒绝,当访问过多,就可能造成拒绝访问,被屏蔽IP的问题。这个时候就需要使⽤代理IP去访问。 代理IP实现“瞒天过海”之计,让被访问的服务器显⽰的IP地址是爬⾍程序设定的IP,⽽⾮计算机真实的IP地址,就算发现是爬⾍程序,被屏蔽的IP是代理IP,⽽⾮真实的计算机IP地址。
对CNKI⽹站进⾏爬⾍时,发现当爬取450篇信息后,IP 就会被屏蔽,需要填写验证码,导致⽆法连续爬取,因此需要设置代理IP。 代理IP 地址可以去⼀些⽹站去爬取,本程序使⽤了:www.xicidaili/nt/提供的免费代理IP。
5. 分功能设置函数:
为了使得代码逻辑清晰,可以分不同的⽬的设置不同的函数。注意各个函数之间的参数传递,容易出错。
6. ⽹站源码⾃⾝的不规则:
在测试程序过程中,⼤部分⽂章爬取成功,但是,存在⼩部分⽂章爬取失败,按照道理,编码⼀样话,那应该同时成功,同时失败。选择爬取“成功”和“失败”两篇⽂章的⽹页源码,发现存在不⼀致,需
要通过技术处理,得到⼀致结果:
例如:if len(ftext_r.xpath('//ul[@class='break']/li/text()'))==3:
if len(ftext_r.xpath('//ul[@class='break']/li/text()'))==4:
这⾥ ul 标签 class属性为 break 下 可能存在4 li 标签, 也能是3个 li标签,所有通过判断语句,然后分别处理获取需要的信息。
7. 关键点设置提⽰信息:
在爬取较多⽹页时,难保证不出问题,需要不断改进程序的适应度,但是,若果出现问题,逐⼀⽹页排查问题的⼯作量太⼤。可以在每页爬取的时候提醒是否爬取成功。
通过这些提⽰信息,就可以⽅便的定位到某个出问题的⽹页,⽅便排查。
# ---------------------------------------
完整Python爬⾍代码:
#(代码补充说明:标注“参数设置”后⾯的代码中可以通过简单修改,就可以爬取不同主题,不同页数,使⽤不同的代理IP )
*---------------------------------------
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''
Created on Thu Nov 9 21:37:30 2017
@author: liu kuanbin
'''
#-加载将会使⽤到的函数库
import requests # 读取⽹页
from lxml import etree # ⽤于解析⽹页
from openpyxl import Workbook # 创建表格并⽤于数据写⼊
from bs4 import BeautifulSoup # 解析⽹页
import random # 随机选择代理Ip
#--获得代理IP列表
def get_ip_list(urlip,headers2):
web_data = (urlip,headers=headers2)
soup = BeautifulSoup(, 'lxml')
ips = soup.find_all('tr')
ip_list = []
for k in range(1, len(ips)):
ip_info = ips[k]
tds = ip_info.find_all('td')
ip_list.append(tds[1].text + ':' + tds[2].text)
return ip_list
#-从代理IP列表⾥⾯随机选择⼀个
def get_random_ip(ip_list):
proxy_list = []
for ip in ip_list:
proxy_list.append('' + ip)
url编码和utf8区别
proxy_ip = random.choice(proxy_list)
proxies = {'http': proxy_ip}
return proxies
#-定义获取⽂章列表对应的链接的函数
def get_data(urllist,headers,proxies):
j=0 # 初始化j的取值
for urli in urllist:
try:
j=j+1
num=15*(i-pagestart)+j # 第多少篇
test=str(urli)
# 是否使⽤代理去爬⾍就在下⾯这⼀⾏代码中,是否添加: proxies=proxies
(test,headers=headers) # 设置Headers项; 这⾥添加是否使⽤代理去访问:
ding).decode('utf-8') # 对具体进⾏转码,获得可以正常读取的⽂档;
ftext_r=etree.HTML(ftext) # 对具体页进⾏ xpath 解析;
#---------------------------
if len(ftext_r.xpath('//ul[@class='break']/li/text()'))==3:
if len(ftext_r.xpath('//ul[@class='break']/li/text()'))==4:
if len(str(ftext_r.xpath('//div[@class='author summaryRight']/p[2]/a/text()')))==2:
else:
# str(ftext_r.xpath('//div[@class='author summaryRight']/p[2]/a/text()'))
第⼀作者及所属刊物及时间
print('爬⾍'+str(15*(pageend-pagestart+1))+'篇⽂章信息的第'+str(num)+'篇爬取成功!!')
except:
print('爬⾍第'+str(i)+'页中的第'+str(j)+'篇爬⾍失败')
#---创建表格,待接收数据信息---#
wb = Workbook() # 在内存中创建⼀个workbook对象,⽽且会⾄少创建⼀个 worksheet
ws = wb.active # 获取当前活跃的worksheet,默认就是第⼀个worksheet
#---------------参数设置
if __name__=='__main__':
pagestart=1
pageend=90
keywords='精准扶贫' ### 查询的主题
url='searchki/search.aspx?q='+str(keywords)+'&rank=citeNumber&cluster=all&val=CJFDTOTAL&p='
urlip = 'www.xicidaili/nt/' # 提供代理IP的⽹站
headers={
'Referer':'searchki/search.aspx?
q=qw:%e7%b2%be%e5%87%86%e6%89%b6%e8%b4%ab&cluster=all&val=&p=0',
'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_0) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/61.0.3163.100 Safari/537.36',
'Cookie':'cnkiUserKey=158f5312-0f9a-cc6a-80c1-30bc5346c174; Ecp_ClientId=41711082042033584
41;
UM_distinctid=15fa39ba58f5d2-0bbc0ba0169156-31637c01-13c680-15fa39ba5905f1; SID_search=201087;
ASP.NET_SessionId=glrrdk550e5gw0fsyobrsr45; CNZZDATA2643871=cnzz_eid%3D610954823-1510276064-
null%26ntime%3D1510290496; CNZZDATA3636877=cnzz_eid%3D353975078-1510275934-
null%26ntime%3D1510290549; SID_sug=111055;
LID=WEEvREcwSlJHSldRa1FhcTdWZDhML1NwVjBUZzZHeXREdU5mcG40MVM4WT0=$9A4hF_YAuvQ5obgVAqNKPCYcEjKensW4
}
headers2={
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) C
hrome/53.0.2785.143
Safari/537.36'
}
#------------------------------------------
for i in range(pagestart,pageend+1):
try:
## 得到⼀个代理 IP
ip_list = get_ip_list(urlip,headers2) # 获得代理IP列表
proxies = get_random_ip(ip_list) # 获得随机的⼀个代理IP
# 获得每⼀页⾥⾯⽂章的 urllist
url_all=url+str(15*(i-1))
#获得每⼀页的⽂章具体⽂章信息页⾯的链接
(url_all,headers=headers) # 获得⽹页源码 ,proxies=proxies
# print(utf16_response.decode('utf-16'))
ding).decode('utf-8') # 对⽹页信息进⾏转化成为可以正常现实的 UTF-8格式
r=etree.HTML(file) # 获取⽹页信息,并且解析 使⽤xpath
urllist=r.xpath('//div[@class='wz_content']/h3/a[1]/@href') # 获得当前页所有⽂章的进⼊链接
# 获得每页urllist的⽂章信息,并且存到构建的表格中
get_data(urllist,headers,proxies)
except:
print('第'+str(i)+'页在爬取时候发⽣错误')
wb.save('知⽹⽂章信息汇总.xlsx') # 最后保存搜集到的数据
最终爬取到的数据:
通过得到的数据资料,可以⽤于接卸来的分析,研究“精准扶贫”此类主题⽂献的各种信息。例如: 那些单位发表的论⽂最多, 通过词云
图可以看出此类⽂章主要的研究⽅向等等,可以⽤于各种有意思的分析。
此类玩数据,就留待下次分析。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论