实现功能:代理、限速、深度、反爬
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. linux下read命令详解

    要与Linux交互,脚本获取键盘输入的结果是必不可少的,read可以读取键盘输入的字符. read [-rs] [-a ARRAY] [-d delim] [-n nchars] [-N nchars ...

  2. SpringBoot使用CORS解决跨域请求问题

    什么是跨域? 同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源. 同源策略是浏览器安全的基石. 如果一个请求地址里面的协议.域名和端口号都相同,就属于同源. ...

  3. flashfxp 数据socket错误 连接已超时 filezilla

    最近windows server 开启了防火墙后发现flashfxp连不上,报超时. 1,服务端的动态端口从指定的范围内取, 2,防火墙开启范围内端口. 参考:http://jingyan.baidu ...

  4. Mosquitto-1.5在Linux上的安装以及Android客户端的实现

    一.关于MQTT MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的" ...

  5. Caffe 根据log信息画出loss,accuracy曲线

    在执行训练的过程中,若指定了生成log信息,log信息包含初始化,网络结构初始化和训练过程随着迭代数的loss信息. 注意生成的log文件可能没有.log后缀,那么自己加上.log后缀.如我的log信 ...

  6. h5页面 内嵌h5页面遇到的问题

    1.input框无法获取焦点输入内容 input { -webkit-user-select: auto; } 2.div里面放img标签有3px的距离 div { font-size: 0; } i ...

  7. C#修改json文件中的某些值

    using Newtonsoft.Json; JsonSerializer serialiser = new JsonSerializer(); string newContent = string. ...

  8. 两个1/x类的广义函数

    [转载请注明出处]http://www.cnblogs.com/mashiqi 2017/04/15 1.$\text{p.v.}\,\frac{1}{x}$ 因为$(x \ln x - x)' = ...

  9. maven pom.xml配置文件详解

    1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/ ...

  10. js post下载相当于 location.href

    /** *参数说明: url:下载地址,val:需要提交的参数值,具体类型和个数自行扩展 * 参数可以用obj = {url:""",val1:"111&quo ...