实现功能:代理、限速、深度、反爬
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. html盒子铺满全屏

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. 安装一个Linux

    Linux--虚拟机的的安装: 首先需要一个可执行(VMware-workstation-full-14.1.2-8497320.exe)的文件和一个Linux(CentOS-7-x86_64-DVD ...

  3. LCA最近公共祖先模板代码

    vector模拟邻接表: #include<iostream> #include<cstdio> #include<cstring> #include<cma ...

  4. Quartz定时器+Spring + @Autowired注入 空指针异常

    在Quartz的定时方法里引用@Autowired注入Bean,会报空指针错误 解决办法: 第一种方法:(推荐,简单,亲测可行) 使用@Resource(name="指定要注入的Bean&q ...

  5. 指导手册02:伪分布式安装Hadoop(ubuntuLinux)

    指导手册02:伪分布式安装Hadoop(ubuntuLinux)   Part 1:安装及配置虚拟机 1.安装Linux. 1.安装Ubuntu1604 64位系统 2.设置语言,能输入中文 3.创建 ...

  6. SQL Server--------SQL Server常用(查看注释,新增注释,生成实体,查看表结构信息,case when...)

    --新增字段: ALTER TABLE line_info ADD line_remark NVARCHAR(MAX) DEFAULT ''  EXECUTE sp_addextendedproper ...

  7. java 集合之Map

    Map的功能方法 方法put(Object key,Object value)添加一个"值"(想要得东西)和与"值"相关的"键"(key)( ...

  8. cocos2d-x3.17 整体概述

    首先,cocos引擎有三个版本:C++,Lua,Js.其底层代码是由C++编写,通过脚本文件绑定到Lua与Js,所以我们之后解析的都是cocos2d-x.其次,cocos安装等就不概述了,百度一大堆. ...

  9. latex中使用listings显示代码

    \documentclass[12pt,a4paper]{article}\usepackage{ctex}\usepackage{listings}\usepackage{xcolor}\begin ...

  10. word转换成HTML 以及IE不兼容问题

    public static bool WordToHtml(string wordFileName, string htmlFileName) { try { Object oMissing = Sy ...