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求解平方根的方法
Mar 11 Python
Python中死锁的形成示例及死锁情况的防止
Jun 14 Python
python3使用SMTP发送简单文本邮件
Jun 19 Python
python解析xml简单示例
Jun 21 Python
Python Django 前后端分离 API的方法
Aug 28 Python
python编写计算器功能
Oct 25 Python
使用matplotlib绘制图例标签中带有公式的图
Dec 13 Python
基于python3的socket聊天编程
Feb 17 Python
python Yaml、Json、Dict之间的转化
Oct 19 Python
Python 实现图片转字符画的示例(静态图片,gif皆可)
Nov 05 Python
Python中的np.argmin()和np.argmax()函数用法
Jun 02 Python
Python如何利用pandas读取csv数据并绘图
Jul 07 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
解析PHP中DIRECTORY_SEPARATOR,PATH_SEPARATOR两个常量的作用
2013/06/21 PHP
浅谈COOKIE和SESSION区别
2015/07/19 PHP
CodeIgniter整合Smarty的方法详解
2017/08/25 PHP
thinkPHP3.2.3结合Laypage实现的分页功能示例
2018/05/28 PHP
Yii框架自定义数据库操作组件示例
2019/11/11 PHP
js改变文章字体大小的实例代码
2013/11/27 Javascript
浅谈setTimeout 与 setInterval
2015/06/23 Javascript
Jquery插件easyUi实现表单验证示例
2015/12/15 Javascript
基于Bootstrap的Metronic框架实现页面链接收藏夹功能
2016/08/29 Javascript
jquery实现手机端单店铺购物车结算删除功能
2017/02/22 Javascript
如何解决vue与传统jquery插件冲突
2017/03/20 Javascript
jQuery实现动态添加节点与遍历节点功能示例
2017/11/09 jQuery
微信小程序 功能函数小结(手机号验证*、密码验证*、获取验证码*)
2017/12/08 Javascript
微信小程序点击列表跳转到对应详情页过程解析
2019/09/26 Javascript
vue监听用户输入和点击功能
2019/09/27 Javascript
关于angular引入ng-zorro的问题浅析
2020/09/09 Javascript
vue操作dom元素的3种方法示例
2020/09/20 Javascript
解决Vue keep-alive 调用 $destory() 页面不再被缓存的情况
2020/10/30 Javascript
简单的Python2.7编程初学经验总结
2015/04/01 Python
Python中join和split用法实例
2015/04/14 Python
python创建列表并给列表赋初始值的方法
2015/07/28 Python
使用rst2pdf实现将sphinx生成PDF
2016/06/07 Python
Python实现删除文件中含“指定内容”的行示例
2017/06/09 Python
详解python中的Turtle函数库
2018/11/19 Python
利用Tensorboard绘制网络识别准确率和loss曲线实例
2020/02/15 Python
使用SimpleITK读取和保存NIfTI/DICOM文件实例
2020/07/01 Python
python文件及目录操作代码汇总
2020/07/08 Python
python Gabor滤波器讲解
2020/10/26 Python
Nike英国官网:Nike.com (UK)
2017/02/13 全球购物
优秀的自荐信要注意哪些
2014/01/03 职场文书
中学生班主任评语
2014/01/30 职场文书
小学生家长评语大全
2014/02/10 职场文书
乡镇综治宣传月活动总结
2014/07/02 职场文书
关于读书的演讲稿800字
2014/08/27 职场文书
安全生产月宣传标语
2014/10/06 职场文书
SQL中去除重复数据的几种方法汇总(窗口函数对数据去重)
2023/05/08 MySQL