php 抓取网页 源码(使用Python爬虫技术快速获取知网1000多篇某个主题的文章(图))
优采云 发布时间: 2022-02-15 21:22php 抓取网页 源码(使用Python爬虫技术快速获取知网1000多篇某个主题的文章(图))
本文介绍使用Python爬虫技术快速获取CNKI上1000多篇文章的标题、作者、作者单位、被引用次数、下载次数、发表次数、发表时间、文章摘要。
刚开始学习爬虫的时候,想到了爬CNKI学科文献,抓取文章感兴趣的话题,获取相关文章的基本信息和摘要,从而快速了解某个领域的研究。过程、重点等
经过不断的修改,这个目标终于实现了。
在这个爬虫程序编写过程中,有几个问题需要注意。
选择适当的 网站 条目;
一般我们进入CNKI,发现这个网站很难爬取,也很难获取网站的完整源码,最后发现可以获取完整源码.
分析 网站 URL:
复制图中的URL,得到如下URL: %E7%B2%BE%E5%87%86%E6%89%B6%E8%B4%AB&rank=citeNumber&cluster=all&val=&p=0 发现被编码, 复制的 URL 需要使用 urllib.unquote() 进行解码。
解析解码后的URL:精准扶贫&rank=citeNumber&cluster=all&val=CJFDTOTAL&p=0;通过选择不同的排序,不同的搜索关键词,不同的文档类型,可以确定'q='字段控制搜索关键词,'rank='控制排序方式,"p= " 字段控制翻页,步长为 15。最终的搜索 URL 为:url='
转码问题:
在爬取网页的过程中,发现获取的网页源代码打印出来后出现乱码。最后发现网页源代码的编码方式不是UTF-8。因此,为了获得可以用于解析的网页源代码,需要对源代码进行转码,首先将原来的编码方式转换为通用的Unicode,然后转码为:UTF-8,转码方法:
f=requests.get(test,headers=headers) # 获取网页源代码
ftext=f.text.encode(f.encoding).decode('utf-8') # 转码为可解析编码
代理IP问题:
在爬取过程中,爬取少量网页和爬取大量网页是有很大区别的。少爬取网页意味着被爬取的服务器不会拒绝它。当访问过多时,可能会导致拒绝访问和阻塞IP的问题。这时候就需要使用代理IP来访问了。代理IP实现了“欺骗”策略,使得被访问的服务器显示的IP地址是爬虫程序设置的IP,而不是电脑的真实IP地址。即使发现是爬虫程序,被屏蔽的IP也是代理IP,而不是真实的电脑IP地址。
爬取CNKI网站时,发现爬取450条信息后,IP会被屏蔽,需要填写验证码,导致无法连续爬取,所以需要设置代理IP。代理IP地址可以去一些网站爬取,本程序使用:提供的免费代理IP。
子功能设置功能:
为了使代码逻辑清晰,可以针对不同的目的设置不同的功能。注意函数之间的参数传递,容易出错。
网站源码本身的不规范:
在程序测试过程中,大部分文章爬取成功,但也有少数文章爬取失败。根据推理,如果编码相同,则应该同时成功和失败。选择爬取“成功”和“失败”两个文章页面的源码,发现有不一致的地方,需要通过技术程序处理,才能得到一致的结果:
例如:如果 len(ftext_r.xpath('//ul[@class='break']/li/text()'))==3:
ws.cell(row=num+1, column=6).value=ftext_r.xpath('//ul[@class='break']/li[2]/text()')[0]
ws.cell(row=num+1, column=7).value=ftext_r.xpath('//ul[@class='break']/li[3]/text()')[0]
如果 len(ftext_r.xpath('//ul[@class='break']/li/text()'))==4:
ws.cell(row=num+1, column=6).value=ftext_r.xpath('//ul[@class='break']/li[3]/text()')[0]
ws.cell(row=num+1, column=7).value=ftext_r.xpath('//ul[@class='break']/li[4]/text()')[0]
这里,ul标签的class属性下可能有4个li标签或者3个li标签作为break,都经过判断语句,然后分别处理需要的信息。
关键点设置提示信息:
爬取很多网页时,很难保证不会出现问题,需要不断提高程序的适应度。但是,如果有问题,要一一检查问题,工作量太大。可以在爬取每个页面时提醒是否爬取成功。
通过这些提示信息,您可以轻松定位出问题的网页,方便排查。
#----------------------------------------
完整的Python爬虫代码:
#(代码补充说明:“参数设置”后面的代码可以简单修改爬取不同主题、不同页数、使用不同代理IP)
*----------------------------------------
#!/usr/bin/env python3
# -*- 编码:utf-8 -*-
'''
创建于 2017 年 11 月 9 日星期四 21:37:30
@作者:刘宽斌
'''
#-加载将要使用的函数库
导入请求 # 读取网页
from lxml import etree # 用于解析网页
from openpyxl import Workbook # 创建表并用于数据写入
from bs4 import BeautifulSoup #解析网页
import random # 随机选择代理IP
#--获取代理IP列表
def get_ip_list(urlip,headers2):
web_data = requests.get(urlip,headers=headers2)
汤= BeautifulSoup(web_data.text,'lxml')
ips = soup.find_all('tr')
ip_list = []
对于范围内的k(1,len(ips)):
ip_info = ips[k]
tds = ip_info.find_all('td')
ip_list.append(tds[1].text + ':' + tds[2].text)
返回 ip_list
#- 从代理IP列表中随机选择一个
def get_random_ip(ip_list):
代理列表 = []
对于 ip_list 中的 ip:
proxy_list.append('#x27; + ip)
proxy_ip = random.choice(proxy_list)
代理 = {'http': proxy_ip}
返回代理
#-定义获取文章列表对应链接的函数
def get_data(urllist, headers, proxies):
j=0 # 初始化j的值
对于 urllist 中的 url:
尝试:
j=j+1
num=15*(i-pagestart)+j # 有多少篇文章
测试=str(url)
# 是否使用代理爬取爬虫在下面这行代码中,是否添加:proxies=proxies
f=requests.get(test,headers=headers) # 设置Headers项;这里添加是否使用代理访问:
ftext=f.text.encode(f.encoding).decode('utf-8') # 将具体内容转码得到可以正常阅读的文档;
ftext_r=etree.HTML(ftext) # 对特定页面进行xpath解析;
ws.cell(row=num+1, column=1).value='文章'+str(num)+'文章文章信息'
ws.cell(row=num+1, column=2).value=str(ftext_r.xpath('//title/text()')[0]).replace(' - 中国学术期刊网络出版通用库','') # 获取 文章 标题
ws.cell(row=num+1, column=3).value=str(ftext_r.xpath('//div[@class='author summaryRight']/p[1]/a/text() ')) # 获取作者姓名
#----------------------------------------
如果 len(ftext_r.xpath('//ul[@class='break']/li/text()'))==3:
ws.cell(row=num+1, column=6).value=ftext_r.xpath('//ul[@class='break']/li[2]/text()')[0]
ws.cell(row=num+1, column=7).value=ftext_r.xpath('//ul[@class='break']/li[3]/text()')[0]
如果 len(ftext_r.xpath('//ul[@class='break']/li/text()'))==4:
ws.cell(row=num+1, column=6).value=ftext_r.xpath('//ul[@class='break']/li[3]/text()')[0]
ws.cell(row=num+1, column=7).value=ftext_r.xpath('//ul[@class='break']/li[4]/text()')[0]
if len(str(ftext_r.xpath('//div[@class='author summaryRight']/p[2]/a/text()')))==2:
ws.cell(row=num+1, column=4).value=str(ftext_r.xpath('//div[@class='author summaryRight']/p[3]/a/text() '))# 获取作者单位
别的:
ws.cell(row=num+1, column=4).value=str(ftext_r.xpath('//div[@class='author summaryRight']/p[2]/a/text() '))
# str(ftext_r.xpath('//div[@class='作者 summaryRight']/p[2]/a/text()'))
ws.cell(row=num+1, column=5).value=ftext_r.xpath('//div[@id='weibo']/input/@value')[0] # 第一作者和它的出版和时间
ws.cell(row=num+1, column=8).value=str(ftext_r.xpath('//span[@id='ChDivKeyWord']/a/text()')) # 文章关键词
ws.cell(row=num+1, column=9).value=ftext_r.xpath('//span[@id='ChDivSummary']/text()')[0] # 得到 文章 总结
print('爬虫'+str(15*(pageend-pagestart+1))+'文章信息的第一个'+str(num)+'爬取成功!!')
除了:
print(''+str(j)+'爬虫在'+str(i)+'爬虫页面失败')
#---创建表单,接收数据---#
wb = Workbook() # 在内存中创建一个工作簿对象,至少会创建一个工作表
ws = wb.active # 获取当前活动的工作表,默认是第一个工作表
ws.cell(row=1, column=1).value ='No'
ws.cell(row=1, column=2).value ='Title'
ws.cell(row=1, column=3).value ='Author'
ws.cell(row=1, column=4).value ='研究所'
ws.cell(row=1, column=5).value ='Journal'
ws.cell(row=1, column=6).value ='Cites'
ws.cell(row=1, column=7).value ='下载'
ws.cell(row=1, column=8).value ='Keywords'
ws.cell(row=1, column=9).value ='Abstart'
#---------------参数设置
如果名称=='主要':
页面开始=1
页面结束=90
keywords='精准扶贫'###查询主题
网址=''
urlip = ' # 网站 提供代理IP
标头={
'Referer':':%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 = 43358441; UM_distinctid = 15fa39ba58f5d2-0bbc0ba7c01-13c680-15fa39ba5905f1;SID_search = 201087; ASP.NET_SessionId = glrrdk550e5gw0fsyobrsr45; CNZZDATA2643871 = cnzz_eid% 3D61276064-null% 26ntime % 3D1510290496; CNZZDATA3636877 = cnzz_eid% 3D35397534-null% 26ntime% 3D1510290549; SID_sug = 111055; LID = WEEvREcwSlJHSldRa1FhcTdWZDhML1NwVjBUZzZHeXREdU5mcG40MVM4WT0 = $ 9A4hF_YAuvQ5obgVAqNKPCYcEjKensW4IQMovwHtwkF4VYPoHbKxJw !! ',
}
标头2={
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/ 53.0.2785.143 Safari/537.36'
}
#------------------------------------------------ ---
对于我在范围内(pagestart,pageend+1):
尝试:
##获取代理IP
ip_list = get_ip_list(urlip,headers2) # 获取代理IP列表
proxies = get_random_ip(ip_list) # 获取随机代理IP
# 获取每个页面中文章的urllist
url_all=url+str(15*(i-1))
#获取每个页面的文章具体文章信息页面的链接
response=requests.get(url_all,headers=headers) # 获取网页的源代码,proxies=proxies
# print(utf16_response.decode('utf-16'))
file=response.text.encode(response.encoding).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,标题,代理)
除了:
print('爬取页面时出错'+str(i)+'')
wb.save('HowNet文章Information Summary.xlsx') # 最后保存采集到的数据
最终爬取的数据:
获得的数据可用于传入分析,研究“精准扶贫”等主题的各种信息。比如那些单位发表论文最多,词云图展示了这类文章的主要研究方向等,可以用来做各种有趣的分析。
这样的播放数据将留待下一次分析。