php 抓取网页 源码(使用Python爬虫技术快速获取知网1000多篇某个主题的文章(图))

优采云 发布时间: 2022-02-15 21:22

  php 抓取网页 源码(使用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') # 最后保存采集到的数据

  最终爬取的数据:

  获得的数据可用于传入分析,研究“精准扶贫”等主题的各种信息。比如那些单位发表论文最多,词云图展示了这类文章的主要研究方向等,可以用来做各种有趣的分析。

  这样的播放数据将留待下一次分析。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线