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 tornado队列示例-一个并发web爬虫代码分享
Jan 09 Python
Python实现计算字符串中出现次数最多的字符示例
Jan 21 Python
Python检查ping终端的方法
Jan 26 Python
Python 使用list和tuple+条件判断详解
Jul 30 Python
Flask使用Pyecharts在单个页面展示多个图表的方法
Aug 05 Python
Python 操作mysql数据库查询之fetchone(), fetchmany(), fetchall()用法示例
Oct 17 Python
通过 Django Pagination 实现简单分页功能
Nov 11 Python
python从zip中删除指定后缀文件(推荐)
Dec 05 Python
Python批量启动多线程代码实例
Feb 18 Python
Python3基于print打印带颜色字符串
Jul 06 Python
Python爬虫定时计划任务的几种常见方法(推荐)
Jan 15 Python
python解包用法详解
Feb 17 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安装攻略:常见问题解答(三)
2006/10/09 PHP
dhtmlxTree目录树增加右键菜单以及拖拽排序的实现方法
2013/04/26 PHP
解析PHP将对象转换成数组的方法(兼容多维数组类型)
2013/06/21 PHP
PHP实现无限极分类图文教程
2014/11/25 PHP
php实现图片上传并进行替换操作
2016/03/15 PHP
PHP微信发送推送消息乱码的解决方法
2019/02/28 PHP
php设计模式之适配器模式原理、用法及注意事项详解
2019/09/24 PHP
php5.3/5.4/5.5/5.6/7常见新增特性汇总整理
2020/02/27 PHP
PHP xpath提取网页数据内容代码解析
2020/07/16 PHP
学习并汇集javascript匿名函数
2010/11/25 Javascript
javascript的日期对象、数组对象、二维数组使用说明
2014/12/22 Javascript
javascript将异步校验表单改写为同步表单
2015/01/27 Javascript
jquery实现华丽的可折角广告代码
2015/09/02 Javascript
基于javascript html5实现多文件上传
2016/03/03 Javascript
深入理解setTimeout函数和setInterval函数
2016/05/20 Javascript
解析NodeJs的调试方法
2016/12/11 NodeJs
浅析上传头像示例及其注意事项
2016/12/14 Javascript
Node.js制作简单聊天室
2017/01/12 Javascript
vue实现添加标签demo示例代码
2017/01/21 Javascript
jQuery图片轮播功能实例代码
2017/01/29 Javascript
深入理解JS中Number(),parseInt(),parseFloat()三者比较
2018/08/24 Javascript
python实现大转盘抽奖效果
2019/01/22 Python
对python中if语句的真假判断实例详解
2019/02/18 Python
在linux下实现 python 监控usb设备信号
2019/07/03 Python
pyinstaller打包单文件时--uac-admin选项不起作用怎么办
2020/04/15 Python
Sunglasses Shop丹麦:欧洲第一的太阳镜在线销售网站
2017/10/22 全球购物
英国豪华针织品牌John Smedley的在线销售商:The Outlet by John Smedley
2018/04/08 全球购物
联想韩国官网:Lenovo Korea
2018/05/10 全球购物
小学毕业感言300字
2014/02/19 职场文书
安全教育感言
2014/03/04 职场文书
食品安全工作实施方案
2014/03/26 职场文书
情人节寄语大全
2014/04/11 职场文书
2015年办公室人员工作总结
2015/05/15 职场文书
高考要来啦!用Python爬取历年高考数据并分析
2021/06/03 Python
Python IO文件管理的具体使用
2022/03/20 Python
什么是SOLID
2022/03/24 Javascript