实现功能:代理、限速、深度、反爬
import re
import queue
import urllib.parse
import urllib.robotparser
import time
from urllib import request
from datetime import datetime
 
def download(url, user_agent="wsap", num=2):
    print("Downloading:"+url)
    try:
        req = request.Request(url)
        req.add_header('user_agent', user_agent)
        html = request.urlopen(req).read()
    except Exception as e:
        print('Download error:')
        html = None
        if num > 0:
            if hasattr(e, "code") and 500 <= e.code < 600:
                return download(url, user_agent, num-1)
    return html
 
def link_crawler(seed_url, link_regex=None, delay=5, max_depth=-1, max_urls=-1, headers=None, user_agent='BadCrawler', proxy=None, num_retries=1):
    crawl_queue = queue.deque([seed_url])
    seen = {seed_url: 0}
    num_urls = 0
    rp = get_robots(seed_url)
    throttle = Throttle(delay)
    headers = headers or {}
    if user_agent:
        headers['User-agent'] = user_agent
    while crawl_queue:
        url = crawl_queue.pop()
        if rp.can_fetch(user_agent, url):
            throttle.wait(url)
            html = download(url)
            links = []
            depth = seen[url]
            if depth != max_depth:
                if link_regex:
                    links.extend(link for link in get_links(html) if re.match(link_regex, link))
                for link in links:
                    link = normalize(seed_url, link)
                    if link not in seen:
                        seen[link] = depth +1
                        if same_domain(seed_url, link):
                            crawl_queue.append(link)
            num_urls += 1
            if num_urls == max_urls:
                break
        else:
            print('Blocked by robots.txt:'+url)
 
class Throttle:
    def __init__(self, delay):
        self.delay = delay
        self.domains = {}
 
    def wait(self, url):
        domain = urllib.parse.urlparse(url).netloc
        last_accessed = self.domains.get(domain)
        if self.delay > 0 and last_accessed is not None:
            sleep_secs = self.delay - (datetime.now() - last_accessed).seconds
            if sleep_secs > 0:
                time.sleep(sleep_secs)
        self.domains[domain] = datetime.now()
 
def normalize(seed_url,link):
    link, _ = urllib.parse.urldefrag(link)
    return urllib.parse.urljoin(seed_url, link)
 
def same_domain(url1, url2):
    return urllib.parse.urlparse(url1).netloc == urllib.parse.urlparse(url2).netloc
 
def get_robots(url):
    rp = urllib.robotparser.RobotFileParser()
    rp.set_url(urllib.parse.urljoin(url, '/robots.txt'))
    rp.read()
    return rp
 
def get_links(html):
    webpage_regex = re.compile('<a[^>]+href=["\'](.*?)["\']', re.IGNORECASE)
    html = html.decode('utf-8')
    return webpage_regex.findall(html)
 
if __name__ == '__main__':
    link_crawler('http://example.webscraping.com', '/places/default/view/', delay=0, num_retries=1, max_depth=1, user_agent='GoodCrawler')

python网页爬虫开发之四-串行爬虫代码示例的更多相关文章

  1. 【DSP开发】串行 RapidIO: 高性能嵌入式互连技术

    串行 RapidIO: 高性能嵌入式互连技术 作者: 德州仪器技术应用工程师 冯华亮/ Brighton Feng/ bf@ti.com 摘要 串行RapidIO针对高性能嵌入式系统芯片间和板间互连而 ...

  2. python 全栈开发,Day47(行级块级标签,高级选择器,属性选择器,伪类选择器,伪元素选择器,css的继承性和层叠性,层叠性权重相同处理,盒模型,padding,border,margin)

    一.HTML中的行级标签和块级标签 块级标签 常见的块级标签:div,p,h1-h6,ul,li,dl,dt,dd 1.独占一行,不和其他元素待在同一行2.能设置宽高3.如果不设置宽高,默认为body ...

  3. 使用pycharm手动搭建python语言django开发环境 - 使用git管理代码(二)

    在pycharm中打开项目,使用File->Version Control->Git.选中git的安装路径并点击确认. 2)在Version Control界面中,配置或新建一个git的主 ...

  4. 串行通讯之Qt

    目录 第1章 Qt 串行通讯    1 1.1 配置.pro文件    1 1.2 查询串口信息    1 1.3 配置.打开串口    3 1.4 setRequestToSend在Windows上 ...

  5. NodeJs使用async让代码按顺序串行执行

    描述 由于nodejs中的函数调用都是异步执行的,而笔者在工程开发中函数A需要四五个参数,而这四五个参数值都是通过函数调用获得,因此按顺序写代码时,执行到函数A时,往往函数A需要的参数值因为参数的异步 ...

  6. Hadoop基础-Protocol Buffers串行化与反串行化

    Hadoop基础-Protocol Buffers串行化与反串行化 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们之前学习过很多种序列化文件格式,比如python中的pickl ...

  7. Hadoop基础-Apache Avro串行化的与反串行化

    Hadoop基础-Apache Avro串行化的与反串行化 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Apache Avro简介 1>.Apache Avro的来源 ...

  8. Python之游戏开发-飞机大战

    Python之游戏开发-飞机大战 想要代码文件,可以加我微信:nickchen121 #!/usr/bin/env python # coding: utf-8 import pygame impor ...

  9. 2018-06-20 中文代码示例视频演示Python入门教程第三章 简介Python

    知乎原链 Python 3.6.5官方入门教程中示例代码汉化后演示 对应在线文档: 3. An Informal Introduction to Python 不知如何合集, 请指教. 中文代码示例P ...

随机推荐

  1. 微信小程序中对于变量的定义

    在页面对应的js文件中: page顶部使用let定义变量,这是定义的全局变量,在当前脚本页面,任何函数中都可以直接使用变量名调用.如果做修改,就直接使用变量等于要更改的值. 使用const定义变量,就 ...

  2. VS2017调试技巧

    Visual Studio的调试技巧   调试技巧是衡量程序员水平的一个重要指标.掌握好的调试技巧与工具的使用方法,也是非常重要的.*** 演示环境: VS2017C#*** 演示用的代码: publ ...

  3. ubuntu1604使用之旅——启动ssh系列

    ---恢复内容开始--- 1.安装ssh的client和server: sudo apt-get install openssh-server openssh-client 2.然后就要安装key: ...

  4. python中如何删除列表中的所有元素

    今天写代码的时候遇到一个小问题,Python中要删除列表中的所有元素.Python本身就提供了pop.remove.del这些删除的函数.我想着用循环实现,结果很麻烦.几番周折上了stackoverf ...

  5. LNMP(一)

    第二十课LNMP(一) 目录 一.LNMP架构介绍 二.MySQL安装 三.PHP安装 四.Nginx介绍 五.Nginx安装 六.扩展 一.LNMP架构介绍 之前已经学习过LAMP架构,与LAMP相 ...

  6. Jsの练习-数组常用方法 -splice()

    splice() 功能:1.可以实现删除,插入和替换. 删除:可以删除任意数量的项,只需指定2个参数:要删除的第一项的位置和要删除的项数. 例如:splice(0,2)会删除数组中的前2项. 插入:可 ...

  7. ulimit系统资源的设定

    使用ulimit -a 可以查看系统使用的资源 core file size 设定core文件的最大值,单位为区块,如果指定为0,不会产生core文件 data seg size 设定数据段的最大值, ...

  8. 网易2018校招内推编程题-堆棋子-C++实现

    链接:https://www.nowcoder.com/questionTerminal/27f3672f17f94a289f3de86b69f8a25b来源:牛客网 [编程题]堆棋子 热度指数:14 ...

  9. js--变量对象总结

    当 JavaScript 代码执行一段可执行代码(executable code)时,会创建对应的执行上下文(execution context). 对于每个执行上下文,都有三个重要属性: 变量对象( ...

  10. jQuery-2.DOM---jQuery遍历

    jQuery遍历之children()方法 jQuery是一个合集对象,如果想快速查找合集里面的第一级子元素,此时可以用children()方法.这里需要注意:.children(selector) ...