抓取网页新闻(百度新闻()收录的大约两千多家的两千多后大所收获)

优采云 发布时间: 2021-10-24 06:22

  抓取网页新闻(百度新闻()收录的大约两千多家的两千多后大所收获)

  小编给大家分享一下Python异步新闻抓取百度新闻爬虫的案例。希望大家看完这篇文章能有所收获,一起来讨论一下吧!

  要爬取新闻,首先要有一个新闻源,即爬取的目标网站。国内新闻网站,从中央到地方,从一般行业到垂直行业,大小不一的新闻网站上千条。百度新闻()收录有两千左右。那么我们先从百度新闻说起。

  打开百度新闻的网站首页:

  我们可以看到这是一个新闻聚合页面,里面列出了很多新闻标题和它们的原创链接。如图所示:

  

  我们的目标是从这里提取这些新闻的链接并下载它们。过程比较简单:

  

  按照这个简单的流程,我们先实现如下简单的代码:

  #!/usr/bin/env python3

# Author: veelion

import re

import time

import requests

import tldextract

def save_to_db(url, html):

    # 保存网页到数据库,我们暂时用打印相关信息代替

    print('%s : %s' % (url, len(html)))

def crawl():

    # 1. download baidu news

    hub_url = 'http://news.baidu.com/'

    res = requests.get(hub_url)

    html = res.text

    # 2. extract news links

    ## 2.1 extract all links with 'href'

    links = re.findall(r'href=[\'"]?(.*?)[\'"\s]', html)

    print('find links:', len(links))

    news_links = []

    ## 2.2 filter non-news link

    for link in links:

        if not link.startswith('http'):

            continue

        tld = tldextract.extract(link)

        if tld.domain == 'baidu':

            continue

        news_links.append(link)

    print('find news links:', len(news_links))

    # 3. download news and save to database

    for link in news_links:

        html = requests.get(link).text

        save_to_db(link, html)

    print('works done!')

def main():

    while 1:

        crawl()

        time.sleep(300)

if __name__ == '__main__':

    main()

  简单解释一下上面的代码:

  1. 使用请求下载百度新闻首页;

  2. 首先用正则表达式提取a标签的href属性,也就是网页中的链接;然后假设非百度外部链接都是新闻链接,找到新闻链接

  3. 将找到的所有新闻链接一一下载并存入数据库;保存到数据库的功能暂时被打印相关信息代替。

  4. 每 300 秒重复步骤 1-3 以获取更新的新闻。

  上面的代码可以工作,但只能工作。没有一点点槽点,所以让我们谈谈并改进这个爬虫。

  1. 添加异常处理

  在写爬虫的时候,尤其是和网络请求相关的代码,一定要有异常处理。目标服务器是否正常,当时的网络连接是否畅通(超时)等都是爬虫无法控制的,所以在处理网络请求时必须处理异常。最好为网络请求设置超时时间,不要在某个请求上花费太多时间。超时导致的识别可能是服务器无法响应,也可能是暂时的网络问题。因此,对于超时异常,我们需要过一段时间再试一次。

  2. 处理服务器返回的状态,如404、500等。

  服务器返回的状态非常重要,它决定了我们的爬虫接下来应该做什么。需要处理的常见状态有:

  301.该URL永久转移到其他URL,以后请求会请求转移的URL

  404,基本上这个网站已经过期了,以后不要试了

  500,服务器出现内部错误,可能是暂时的,请稍后再试

  3. 管理 URL 的状态

  记录失败的 URL,以便稍后重试。对于超时的URL,后面需要重新获取,所以需要记录所有URL的各种状态,包括:

  已成功下载

  多次下载失败,无需重新下载

  下载

  下载失败并重试

  加上对网络请求的各种处理,这个爬虫就强大了很多,不会动不动就异常退出,给后续的运维带来很大的工作量。

  Python爬虫知识点

  在本节中,我们使用了 Python 的几个模块。它们在爬虫中的作用如下:

  1. 请求模块

  它用于发出 http 网络请求和下载 URL 内容。与 Python 自带的 urllib.request 相比,requests 更容易使用。GET 和 POST 很容易获得:

  import requests

res = requests.get(url, timeout=5, headers=my_headers)

res2 = requests.post(url, data=post_data, timeout=5, headers=my_headers)

  get() 和 post() 函数有许多参数可供选择。上面使用了超时设置和自定义标头。更多参数请参考requests文档。

  无论get()还是post(),Requests都会返回一个Response对象,下载的内容就是通过这个对象获取的:

  res.content 是获取到的二进制内容,类型为字节;

  res.text为二进制内容解码后的str内容;

  它首先从响应头中找到编码,如果找不到则通过chardet自动确定编码,并赋值给res.encoding,最后将二进制内容解密为str类型。

  In [1]: import requests

In [2]: r = requests.get('http://epaper.sxrb.com/')

In [3]: r.encoding

Out[3]: 'ISO-8859-1'

In [4]: import chardet

In [5]: chardet.detect(r.content)

Out[5]: {'confidence': 0.99, 'encoding': 'utf-8', 'language': ''}

  以上是用ipython交互式解释器的演示(强烈推荐ipython,比Python自带的解释器好很多)。开通的网站是山西日报数字报。网页源码的代码是utf8,chardet得到的代码也是utf8。而requests判断的编码是ISO-8859-1,那么它返回的文本的中文也会出现乱码。

  请求的另一个有用方面是 Session,它部分类似于浏览器并保存 cookie。您可以稍后使用其会话登录以及与 cookie 相关的爬虫。

  2. 重新模块

  正则表达式主要用于提取html中的相关内容,例如本例中的链接提取。对于更复杂的 html 内容提取,建议使用 lxml。

  3. tldextract 模块

  这是一个第三方模块,需要 pip install tldextract 来安装它。表示顶级域提取,即顶级域提取。前面我们讲了URL的结构,叫做host,是注册域名的子域,com是顶级域TLD。它的结果是这样的:

  In [6]: import tldextract

In [7]: tldextract.extract('http://news.baidu.com/')

Out[7]: ExtractResult(subdomain='news', domain='baidu', suffix='com')

  返回结构收录三部分:子域、域、后缀

  4. 时间模块

  时间是我们在程序中经常用到的一个概念,比如在循环中暂停一段时间,获取当前时间戳等。time模块是一个提供时间相关功能的模块。同时还有一个模块 datetime 也是和时间相关的,可以根据情况使用。

  看完这篇文章,相信你对Python异步新闻抓取百度新闻爬虫的案例有了一定的了解。如果您想了解更多,欢迎关注易宿云行业资讯频道,感谢阅读!

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线