欢迎来到NiceSpace!祝大家开心每一天!
  • python
python爬虫之爬取腾讯新闻

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

如图:

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

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

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

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

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

  1. # -*- coding:utf-8 -*-  
  2.   
  3. #Python抓取网页必备的库  
  4. import urllib   
  5. import urllib2  
  6. #正则表达式  
  7. import re  
  8. #随机数生成  
  9. import random  
  10. #gzip  
  11. import gzip  
  12. from StringIO import StringIO

构建请求头部,请求页面

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

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

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

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

  1. #user-agent  
  2. 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"  
  3.   
  4. #抓取页面接口,参数为地址和referer  
  5. def getHtml(url, referer = None):  
  6.     try:  
  7.         #构建页面请求的头部  
  8.         headers = {'User-Agent':user_agent, "Referer":referer}  
  9.         #构建页面请求  
  10.         request = urllib2.Request(url, headers=headers)  
  11.         #请求目的页面,设置超时时间为45秒  
  12.         response =  urllib2.urlopen(request, timeout = 45)  
  13.   
  14.         html = None  
  15.         #如果经过gzip压缩则先解压,否则直接读取  
  16.         if response.info().get('Content-Encoding') == 'gzip':  
  17.             buf = StringIO(response.read())  
  18.             f = gzip.GzipFile(fileobj=buf)  
  19.             html = f.read()  
  20.         else:  
  21.             html = response.read()  
  22.   
  23.         return html  
  24.     #如果请求异常  
  25.     except urllib2.URLError, e:  
  26.         if hasattr(e, "code"):  
  27.             print e.code  
  28.         elif hasattr(e, "reason"):  
  29.             print e.reason  
  30.         return None  
  31.     #其他异常  
  32.     except Exception,e:  
  33.         return None

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

分析请求地址会发现,每一次的分页请求都是一个地址后面加上一个随机数,而地址中会有本次请求的索引,这样我们就可以构建分页的请求地址,获取每个分页的信息。但是在这之前我们不清楚腾讯要闻中会有多少个分页,分析腾讯新闻的页面,我们最后会发现首页中的一段js标出了腾讯要闻中有多少分页。

因此我们首先抓取腾讯新闻页面内容,获取到要闻有多少分页,在构建分页请求,最后取出页面信息中所有的新闻标题和原文链接就好了。代码如下:

  1. def tencentStart():  
  2.     #腾讯新闻地址  
  3.     INDEX_URL = 'http://news.qq.com/top_index.shtml#hotnews'  
  4.     #腾讯要闻请求地址  
  5.     SUB_URL = "http://news.qq.com/c/2013ywList_{0}.htm"  
  6.     #页面数获取正则  
  7.     PAGE_PATTERNS = 'getString.pageCount.*?=.*?(\d+);'  
  8.     #标题和链接获取正则  
  9.     NEWS_PATTERNS = '<em.*?<a.*?href="(.*?)".*?>(.*?)</a>.*?</em>'  
  10.     #头部信息相关  
  11.     TENCENT_REFER = "http://news.qq.com/"  
  12.     #获取腾讯新闻页面  
  13.     html = getHtml(INDEX_URL)  
  14.     #取得要闻页面总数  
  15.     pattern = re.compile(PAGE_PATTERNS, re.S)  
  16.     countRe = re.search(pattern, html)  
  17.     if html == None:  
  18.         print("未获取到页面")  
  19.         return None  
  20.     count = 1  
  21.     if countRe != None:  
  22.         count = int(countRe.group(1))  
  23.     #构建分页地址,请求分页数据  
  24.     for index in range(count):  
  25.         realIndex = index + 1  
  26.         #构建地址  
  27.         url = SUB_URL.format(realIndex)+'?'+str(random.random())  
  28.         html = getHtml(url, TENCENT_REFER)  
  29.         if html == None:  
  30.             continue  
  31.         #编译标题和链接获取正则  
  32.         pattern = re.compile(NEWS_PATTERNS, re.S)  
  33.         #获取所有标题和链接  
  34.         Res = re.findall(pattern, html)  
  35.         if Res == None:  
  36.             continue  
  37.         #打印所有标题和链接  
  38.         for item in Res:  
  39.             print(item[0]+"\n")  
  40.             print(item[1]+"\n")  
  41.   
  42.   
  43. if __name__ == '__main__':  
  44.     tencentStart()

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

随机文章
四元数的一些整理 3D图形学总结(十)—纹理映射透视矫正 python爬虫之爬取捧腹网段子 selenium+python自动登录脚本 深入理解字符串(编码,解码,乱码问题)
推荐文章