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中关于中文编码问题的处理建议
Apr 08 Python
使用Python3编写抓取网页和只抓网页图片的脚本
Aug 20 Python
Python数据结构与算法之图的广度优先与深度优先搜索算法示例
Dec 14 Python
python批量实现Word文件转换为PDF文件
Mar 15 Python
Flask框架使用DBUtils模块连接数据库操作示例
Jul 20 Python
使用python将图片格式转换为ico格式的示例
Oct 22 Python
python实现本地图片转存并重命名的示例代码
Oct 27 Python
Pytorch训练过程出现nan的解决方式
Jan 02 Python
python 实现Flask中返回图片流给前端展示
Jan 09 Python
Python模块zipfile原理及使用方法详解
Aug 04 Python
Pytorch distributed 多卡并行载入模型操作
Jun 05 Python
python分分钟绘制精美地图海报
Feb 15 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
ADODB的数据库封包程序库
2006/12/31 PHP
PHP 程序授权验证开发思路
2009/07/09 PHP
php用数组返回无限分类的列表数据的代码
2010/08/08 PHP
30 个很棒的PHP开源CMS内容管理系统小结
2011/10/14 PHP
Codeigniter上传图片出现“You did not select a file to upload”错误解决办法
2014/06/12 PHP
JQuery里面的几种选择器 查找满足条件的元素$("#控件ID")
2011/08/23 Javascript
Javascript异步编程模型Promise模式详细介绍
2014/05/08 Javascript
JavaScript基础语法、dom操作树及document对象
2014/12/02 Javascript
JavaScript中的数学运算介绍
2014/12/29 Javascript
Javascript数组操作函数总结
2015/02/05 Javascript
jQuery+Ajax实现无刷新操作
2016/01/04 Javascript
jQuery控制frames及frame页面JS的方法
2016/03/08 Javascript
js实现颜色阶梯渐变效果(Gradient算法)
2017/03/21 Javascript
详解jQuery中关于Ajax的几个常用的函数
2017/07/17 jQuery
shiro授权的实现原理
2017/09/21 Javascript
js正则表达式校验指定字符串的方法
2018/07/23 Javascript
微信小程序实现留言板
2018/10/31 Javascript
如何使用vuex实现兄弟组件通信
2018/11/02 Javascript
Vue在 Nuxt.js 中重定向 404 页面的方法
2019/04/23 Javascript
Vue-cli assets SubDirectory及PublicPath区别详解
2020/08/18 Javascript
Python2 Selenium元素定位的实现(8种)
2019/02/25 Python
利用Python库Scapy解析pcap文件的方法
2019/07/23 Python
python爬虫 urllib模块url编码处理详解
2019/08/20 Python
jupyter 中文乱码设置编码格式 避免控制台输出的解决
2020/04/20 Python
Python Json数据文件操作原理解析
2020/05/09 Python
解决html5中video标签无法播放mp4问题的办法
2017/05/07 HTML / CSS
加拿大领先的牛仔零售商:Bluenotes
2018/01/22 全球购物
台湾专柜女包:KINAZ
2019/12/26 全球购物
高中政治教学反思
2014/01/18 职场文书
大学生学习2014年全国两会心得体会
2014/03/12 职场文书
优秀教师感人事迹材料
2014/05/04 职场文书
国旗下讲话演讲稿
2014/05/08 职场文书
投标诚信承诺书
2014/05/26 职场文书
应届硕士毕业生自荐信
2014/05/26 职场文书
企业仓管员岗位职责
2014/06/15 职场文书
农村党员学习党的群众路线教育实践活动心得体会
2014/11/04 职场文书