python爬虫之爬取腾讯新闻

论坛 期权论坛 脚本     
匿名技术用户   2020-12-23 09:53   56   0

原文链接:http://www.nicemxp.com/articles/11

本文目的抓取腾讯新闻首页中要闻页签下的所有新闻标题和链接。

如图:

地址:http://news.qq.com/top_index.shtml

要闻页签中一般会有几个分页:

所以要爬取要闻下的所有新闻标题和链接就需要一个一个分页的爬取。下面开始写代码。

首先获取腾讯新闻页面内容,写一个获取页面的接口。

先导入本次抓取所必备的库

# -*- coding:utf-8 -*-

#Python抓取网页必备的库
import urllib 
import urllib2
#正则表达式
import re
#随机数生成
import random
#gzip
import gzip
from StringIO import StringIO

构建请求头部,请求页面

#构建页面请求的头部
headers = {'User-Agent':user_agent, "Referer":referer}
#构建页面请求
request = urllib2.Request(url, headers=headers)
#请求目的页面,设置超时时间为45秒
response =  urllib2.urlopen(request, timeout = 45)

请求腾讯新闻页面,返回的页面数据有时会经过gzip压缩,如果直接读取会出现二进制码,所以在处理返回的页面时需要做gizp解压的处理

#如果经过gzip压缩则先解压,否则直接读取
if response.info().get('Content-Encoding') == 'gzip':
 buf = StringIO(response.read())
 f = gzip.GzipFile(fileobj=buf)
 html = f.read()
else:
 html = response.read()

整理代码段,最后封装成页面请求接口

#user-agent
user_agent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"

#抓取页面接口,参数为地址和referer
def getHtml(url, referer = None):
 try:
  #构建页面请求的头部
  headers = {'User-Agent':user_agent, "Referer":referer}
  #构建页面请求
  request = urllib2.Request(url, headers=headers)
  #请求目的页面,设置超时时间为45秒
  response =  urllib2.urlopen(request, timeout = 45)

  html = None
  #如果经过gzip压缩则先解压,否则直接读取
  if response.info().get('Content-Encoding') == 'gzip':
   buf = StringIO(response.read())
   f = gzip.GzipFile(fileobj=buf)
   html = f.read()
  else:
   html = response.read()

  return html
 #如果请求异常
 except urllib2.URLError, e:
  if hasattr(e, "code"):
   print e.code
  elif hasattr(e, "reason"):
   print e.reason
  return None
 #其他异常
 except Exception,e:
  return None

页面请求接口写好后,接下来分析如何要闻页签下的所有数据,要闻页签下有几个分页,当我们在请求分页时可以看出腾讯要闻分页的请求时通过ajax实现的,打开Google浏览器的network,可以看到请求分页时的信息。如图:


分析请求地址会发现,每一次的分页请求都是一个地址后面加上一个随机数,而地址中会有本次请求的索引。

这样我们就可以构建分页的请求地址,获取每个分页的信息。但是在这之前我们不清楚腾讯要闻中会有多少个分页。

分析腾讯新闻的页面,我们最后会发现首页中的一段js标出了腾讯要闻中有多少分页。

因此我们首先抓取腾讯新闻页面内容,获取到要闻有多少分页,在构建分页请求,最后取出页面信息中所有的新闻

标题和原文链接就好了。代码如下:

def tencentStart():
 #腾讯新闻地址
 INDEX_URL = 'http://news.qq.com/top_index.shtml#hotnews'
 #腾讯要闻请求地址
 SUB_URL = "http://news.qq.com/c/2013ywList_{0}.htm"
 #页面数获取正则
 PAGE_PATTERNS = 'getString.pageCount.*?=.*?(\d+);'
 #标题和链接获取正则
 NEWS_PATTERNS = '<em.*?<a.*?href="(.*?)".*?>(.*?)</a>.*?</em>'
 #头部信息相关
 TENCENT_REFER = "http://news.qq.com/"
 #获取腾讯新闻页面
 html = getHtml(INDEX_URL)
 #取得要闻页面总数
 pattern = re.compile(PAGE_PATTERNS, re.S)
 countRe = re.search(pattern, html)
 if html == None:
  print("未获取到页面")
  return None
 count = 1
 if countRe != None:
  count = int(countRe.group(1))
 #构建分页地址,请求分页数据
 for index in range(count):
  realIndex = index + 1
  #构建地址
  url = SUB_URL.format(realIndex)+'?'+str(random.random())
  html = getHtml(url, TENCENT_REFER)
  if html == None:
   continue
  #编译标题和链接获取正则
  pattern = re.compile(NEWS_PATTERNS, re.S)
  #获取所有标题和链接
  Res = re.findall(pattern, html)
  if Res == None:
   continue
  #打印所有标题和链接
  for item in Res:
   print(item[0]+"\n")
   print(item[1]+"\n")


if __name__ == '__main__':
 tencentStart()

最后运行脚本,可以看到打印出的腾讯要闻页签中的所有标题和链接

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP