python使用tornado实现简单爬虫


Posted in Python onJuly 28, 2018

本文实例为大家分享了python使用tornado实现简单爬虫的具体代码,供大家参考,具体内容如下

代码在官方文档的示例代码中有,但是作为一个tornado新手来说阅读起来还是有点困难的,于是我在代码中添加了注释,方便理解,代码如下:

# coding=utf-8
 #!/usr/bin/env python

import time
from datetime import timedelta

try:
  from HTMLParser import HTMLParser
  from urlparse import urljoin, urldefrag
except ImportError:
  from html.parser import HTMLParser
  from urllib.parse import urljoin, urldefrag

from tornado import httpclient, gen, ioloop, queues

 # 设置要爬取的网址
base_url = 'http://www.baidu.com'
 # 设置worker数量
concurrency = 10
 # 此代码会获取base_url下的所有其他url
@gen.coroutine
def get_links_from_url(url):

  try:
    # 通过异步向url发起请求
    response = yield httpclient.AsyncHTTPClient().fetch(url)
    print('fetched %s' % url)
    # 响应如果是字节类型 进行解码
    html = response.body if isinstance(response.body, str) \
      else response.body.decode(errors='ignore')
    # 构建url列表
    urls = [urljoin(url, remove_fragment(new_url))
        for new_url in get_links(html)]
  except Exception as e:
    print('Exception: %s %s' % (e, url))
    # 报错返回空列表
    raise gen.Return([])
  # 返回url列表
  raise gen.Return(urls)


def remove_fragment(url):
  #去除锚点
  pure_url, frag = urldefrag(url)

  return pure_url


def get_links(html):
  #从html页面里提取url
  class URLSeeker(HTMLParser):
    def __init__(self):
      HTMLParser.__init__(self)
      self.urls = []

    def handle_starttag(self, tag, attrs):
      href = dict(attrs).get('href')
      if href and tag == 'a':
        self.urls.append(href)

  url_seeker = URLSeeker()
  url_seeker.feed(html)
  return url_seeker.urls


@gen.coroutine
def main():
  # 创建队列
  q = queues.Queue()
  # 记录开始时间戳
  start = time.time()
  # 构建两个集合
  fetching, fetched = set(), set()

  @gen.coroutine
  def fetch_url():
    # 从队列中取出数据
    current_url = yield q.get()
    try:
      # 如果取出的数据在队列中已经存在 返回
      if current_url in fetching:
        return

      print('fetching %s' % current_url)
      # 如果不存在添加到集合当中
      fetching.add(current_url)
      # 从新放入的链接中继续获取链接
      urls = yield get_links_from_url(current_url)
      # 将已经请求玩的url放入第二个集合
      fetched.add(current_url)

      for new_url in urls:
        # Only follow links beneath the base URL
        # 如果链接是以传入的url开始则放入队列
        if new_url.startswith(base_url):
          yield q.put(new_url)

    finally:
      # 队列内数据减一
      q.task_done()

  @gen.coroutine
  def worker():
    while True:
      # 保证程序持续运行
      yield fetch_url()
  # 将第一个url放入队列
  q.put(base_url)

  # Start workers, then wait for the work queue to be empty.
  for _ in range(concurrency):
    # 启动对应数量的worker
    worker()
  # 等待队列数据处理完成
  yield q.join(timeout=timedelta(seconds=300))
  # 如果两个集合不相等抛出异常
  assert fetching == fetched
  # 打印执行时间
  print('Done in %d seconds, fetched %s URLs.' % (
    time.time() - start, len(fetched)))


if __name__ == '__main__':
  io_loop = ioloop.IOLoop.current()
  io_loop.run_sync(main)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
用Python实现web端用户登录和注册功能的教程
Apr 30 Python
详解Django框架中用户的登录和退出的实现
Jul 23 Python
详解Python中表达式i += x与i = i + x是否等价
Feb 08 Python
完美解决安装完tensorflow后pip无法使用的问题
Jun 11 Python
python自动化生成IOS的图标
Nov 13 Python
python实现dijkstra最短路由算法
Jan 17 Python
Django给admin添加Action的步骤详解
May 01 Python
python执行scp命令拷贝文件及文件夹到远程主机的目录方法
Jul 08 Python
python绘制BA无标度网络示例代码
Nov 21 Python
Tensorflow中tf.ConfigProto()的用法详解
Feb 06 Python
Python 爬取必应壁纸的实例讲解
Feb 24 Python
PyCharm最新激活码PyCharm2020.2.3有效
Nov 18 Python
python编写简易聊天室实现局域网内聊天功能
Jul 28 #Python
对tensorflow 的模型保存和调用实例讲解
Jul 28 #Python
Python Socket编程之多线程聊天室
Jul 28 #Python
python实现点对点聊天程序
Jul 28 #Python
基于python实现聊天室程序
Jul 27 #Python
Python中return self的用法详解
Jul 27 #Python
TensorFlow打印tensor值的实现方法
Jul 27 #Python
You might like
PHPMailer安装方法及简单实例
2008/11/25 PHP
php下使用strpos需要注意 === 运算符
2010/07/17 PHP
PHP取整函数:ceil,floor,round,intval的区别详细解析
2013/08/31 PHP
PHP函数nl2br()与自定义函数nl2p()换行用法分析
2016/04/02 PHP
thinkphp实现分页显示功能
2016/12/03 PHP
Zend Framework实现自定义过滤器的方法
2016/12/09 PHP
详解PHP中的8个魔术常量
2020/07/06 PHP
javascript 当前日期加(天、周、月、年)
2009/08/09 Javascript
让IE8支持DOM 2(不用框架!)
2009/12/31 Javascript
safari,opera嵌入iframe页面cookie读取问题解决方法
2010/06/23 Javascript
js nextSibling属性和previousSibling属性概述及使用注意
2013/02/16 Javascript
JS HTML5 音乐天气播放器(Ajax获取天气信息)
2013/05/26 Javascript
JavaScript中的this关键字介绍与使用实例
2013/06/21 Javascript
使用JQUERY进行后台页面布局控制DIV实现左右式
2014/01/07 Javascript
JS+CSS实现的竖向简洁折叠菜单效果代码
2015/10/22 Javascript
AngularJS 入门教程之HTML DOM实例详解
2016/07/28 Javascript
AngularJS 支付倒计时功能实现思路
2017/06/05 Javascript
javascript实现超好看的3D烟花特效
2020/01/01 Javascript
[01:38]DOTA2第二届亚洲邀请赛中国区预选赛出线战队晋级之路
2017/01/17 DOTA
Python使用sort和class实现的多级排序功能示例
2018/08/15 Python
python输出带颜色字体实例方法
2019/09/01 Python
python取均匀不重复的随机数方式
2019/11/27 Python
使用Keras预训练好的模型进行目标类别预测详解
2020/06/27 Python
英国信箱在线鲜花速递公司:Bloom & Wild
2019/03/10 全球购物
英国领先的在线鱼贩:The Fish Society
2020/08/12 全球购物
WSDL的操作类型主要有几种
2013/07/19 面试题
校园新闻广播稿
2014/01/10 职场文书
实习单位评语
2014/04/26 职场文书
卖车协议书范本4篇
2014/10/01 职场文书
师德师风个人总结
2015/02/06 职场文书
2015年酒店前台工作总结
2015/04/20 职场文书
银行柜员优质服务心得体会
2016/01/22 职场文书
2016年读书月活动总结范文
2016/04/06 职场文书
企业管理不到位检讨书
2019/06/27 职场文书
ThinkPHP5和ThinkPHP6的区别
2021/03/31 PHP
pytorch 使用半精度模型部署的操作
2021/05/24 Python