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实现QQ游戏大家来找茬辅助工具
Sep 14 Python
跟老齐学Python之不要红头文件(1)
Sep 28 Python
Python中操作文件之write()方法的使用教程
May 25 Python
python互斥锁、加锁、同步机制、异步通信知识总结
Feb 11 Python
下载python中Crypto库报错:ModuleNotFoundError: No module named ‘Crypto’的解决
Apr 23 Python
详解django2中关于时间处理策略
Mar 06 Python
使用python实现unix2dos和dos2unix命令的例子
Aug 13 Python
Django REST Framework之频率限制的使用
Sep 29 Python
解决Python logging模块无法正常输出日志的问题
Feb 21 Python
python中使用np.delete()的实例方法
Feb 01 Python
Python带你从浅入深探究Tuple(基础篇)
May 15 Python
Python内置数据结构列表与元组示例详解
Aug 04 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导出oracle库的php代码
2009/04/20 PHP
php支持中文字符串分割的函数
2015/05/28 PHP
php删除数组中重复元素的方法
2015/12/22 PHP
PHPStorm+XDebug进行调试图文教程
2016/06/13 PHP
浏览器无法运行JAVA脚本的解决方法
2008/01/09 Javascript
ie和firefox不兼容的解决方法集合
2009/04/28 Javascript
JS特效实现图片自动播放并可控的效果
2015/07/31 Javascript
正则表达式,替换所有HTML标签的简单实例
2016/11/28 Javascript
JS实现旋转木马式图片轮播效果
2017/01/18 Javascript
Vue框架中正确引入JS库的方法介绍
2017/07/30 Javascript
详解react-router 4.0 下服务器如何配合BrowserRouter
2017/12/29 Javascript
vue+express 构建后台管理系统的示例代码
2018/07/19 Javascript
React+Webpack快速上手指南(小结)
2018/08/15 Javascript
如何在 Vue 表单中处理图片
2021/01/26 Vue.js
跟老齐学Python之私有函数和专有方法
2014/10/24 Python
简单分析Python中用fork()函数生成的子进程
2015/05/04 Python
使用Python程序抓取新浪在国内的所有IP的教程
2015/05/04 Python
Python简单实现自动删除目录下空文件夹的方法
2017/08/29 Python
python使用sqlite3时游标使用方法
2018/03/13 Python
如何利用python制作时间戳转换工具详解
2018/09/12 Python
解决Python下json.loads()中文字符出错的问题
2018/12/19 Python
python的xpath获取div标签内html内容,实现innerhtml功能的方法
2019/01/02 Python
Python异常处理例题整理
2019/07/07 Python
CSS3色彩模式有哪些?CSS3 HSL色彩模式的定义
2016/04/26 HTML / CSS
原装进口全世界:天猫国际
2016/08/03 全球购物
飞利浦比利时官方网站:Philips比利时
2016/08/24 全球购物
英国鲜花递送:Blossoming Gifts
2020/07/10 全球购物
车间副主任岗位职责
2013/12/24 职场文书
《那片绿绿的爬山虎》教学反思
2014/02/27 职场文书
产品生产计划书
2014/05/07 职场文书
无私奉献演讲稿
2014/09/04 职场文书
圣诞晚会主持词
2015/07/01 职场文书
详解Spring Boot使用系统参数表提升系统的灵活性
2021/06/30 Java/Android
Python学习开发之图形用户界面详解
2021/08/23 Python
vue如何实现关闭对话框后刷新列表
2022/04/08 Vue.js
Spring Boot接口定义和全局异常统一处理
2022/04/20 Java/Android