我的编程空间,编程开发者的网络收藏夹
学习永远不晚

大规模异步新闻爬虫中如何实现一个更好的网络请求函数

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

大规模异步新闻爬虫中如何实现一个更好的网络请求函数

这篇文章将为大家详细讲解有关大规模异步新闻爬虫中如何实现一个更好的网络请求函数,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

downloader 的实现

import requestsimport cchardetimport tracebackdef downloader(url, timeout=10, headers=None, debug=False, binary=False):    _headers = {        'User-Agent': ('Mozilla/5.0 (compatible; MSIE 9.0; '                       'Windows NT 6.1; Win64; x64; Trident/5.0)'),    }    redirected_url = url    if headers:        _headers = headers    try:        r = requests.get(url, headers=_headers, timeout=timeout)        if binary:            html = r.content        else:            encoding = cchardet.detect(r.content)['encoding']            html = r.content.decode(encoding)        status = r.status_code        redirected_url = r.url    except:        if debug:            traceback.print_exc()        msg = 'failed download: {}'.format(url)        print(msg)        if binary:            html = b''        else:            html = ''        status = 0    return status, html, redirected_urlif __name__ == '__main__':    url = 'http://news.baidu.com/'    s, html = downloader(url)    print(s, len(html))

这个downloader()函数,内置了默认的User-Agent模拟成一个IE9浏览器,同时接受调用者自定义的headers和timeout。使用cchardet来处理编码问题,返回数据包括:

  • 状态码:如果出现异常,设置为0

  • 内容: 默认返回str内容。但是URL链接的是图片等二进制内容时,注意调用时要设binary=True

  • 重定向URL: 有些URL会被重定向,最终页面的url包含在响应对象里面

新闻URL的清洗

我们先看看这两个新闻网址:

http://xinwen.eastday.com/a/n181106070849091.html?qid=news.baidu.com

http://news.ifeng.com/a/20181106/60146589_0.shtml?_zbs_baidu_news

上面两个带?的网站来自百度新闻的首页,这个问号?的作用就是告诉目标服务器,这个网址是从百度新闻链接过来的,是百度带过来的流量。但是它们的表示方式不完全一样,一个是qid=news.baidu.com, 一个是_zbs_baidu_news。这有可能是目标服务器要求的格式不同导致的,这个在目标服务器的后台的浏览统计程序中可能用得到。

然后去掉问号?及其后面的字符,发现它们和不去掉指向的是相同的新闻网页。

从字符串对比上看,有问号和没问号是两个不同的网址,但是它们又指向完全相同的新闻网页,说明问号后面的参数对响应内容没有任何影响。

正在抓取新闻的大量实践后,我们发现了这样的规律:

新闻类网址都做了大量SEO,它们把新闻网址都静态化了,基本上都是以.html, .htm, .shtml等结尾,后面再加任何请求参数都无济于事。

但是,还是会有些新闻网站以参数id的形式动态获取新闻网页。

那么我们抓取新闻时,就要利用这个规律,防止重复抓取。由此,我们实现一个清洗网址的函数。

g_bin_postfix = set([    'exe', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx',    'pdf',    'jpg', 'png', 'bmp', 'jpeg', 'gif',    'zip', 'rar', 'tar', 'bz2', '7z', 'gz',    'flv', 'mp4', 'avi', 'wmv', 'mkv',    'apk',])g_news_postfix = [    '.html?', '.htm?', '.shtml?',    '.shtm?',]def clean_url(url):    # 1. 是否为合法的http url    if not url.startswith('http'):        return ''    # 2. 去掉静态化url后面的参数    for np in g_news_postfix:        p = url.find(np)        if p > -1:            p = url.find('?')            url = url[:p]            return url    # 3. 不下载二进制类内容的链接    up = urlparse.urlparse(url)    path = up.path    if not path:        path = '/'    postfix = path.split('.')[-1].lower()    if postfix in g_bin_postfix:        return ''    # 4. 去掉标识流量来源的参数    # badquery = ['spm', 'utm_source', 'utm_source', 'utm_medium', 'utm_campaign']    good_queries = []    for query in up.query.split('&'):        qv = query.split('=')        if qv[0].startswith('spm') or qv[0].startswith('utm_'):            continue        if len(qv) == 1:            continue        good_queries.append(query)    query = '&'.join(good_queries)    url = urlparse.urlunparse((        up.scheme,        up.netloc,        path,        up.params,        query,        ''  #  crawler do not care fragment    ))    return url

清洗url的方法都在代码的注释里面了,这里面包含了两类操作:

  • 判断是否合法url,非法的直接返回空字符串

  • 去掉不必要的参数,去掉静态化url的参数

网络爬虫知识点

URL清洗

网络请求开始之前,先把url清洗一遍,可以避免重复下载、无效下载(二进制内容),节省服务器和网络开销。

cchardet 模块

该模块是chardet的升级版,功能和chardet完全一样,用来检测一个字符串的编码。由于是用C和C++实现的,所以它的速度非常快,非常适合在爬虫中用来判断网页的编码。
切记,不要相信requests返回的encoding,自己判断一下更放心。上一节,我们已经列举了一个例子来证明requests对编码识别的错误,如果忘了的话,可以再去回顾一下。

traceback 模块

我们写的爬虫在运行过程中,会出现各种异常,而且有些异常是不可预期的,也不知道它会出现在什么地方,我们就需要用try来捕获异常让程序不中断,但是我们又需要看看捕获的异常是什么内容,由此来改善我们的爬虫。这个时候,就需要traceback模块。
比如在downloader()函数里面我们用try捕获了get()的异常,但是,异常也有可能是cchardet.detect()引起的,用traceback.print_exc()来输出异常,有助于我们发现更多问题。

关于“大规模异步新闻爬虫中如何实现一个更好的网络请求函数”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

大规模异步新闻爬虫中如何实现一个更好的网络请求函数

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

大规模异步新闻爬虫中如何实现一个更好的网络请求函数

这篇文章将为大家详细讲解有关大规模异步新闻爬虫中如何实现一个更好的网络请求函数,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。downloader 的实现import requestsimport ccha
2023-06-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录