实现功能:代理、限速、深度、反爬
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')

最新文章

  1. 驱动开发学习笔记. 0.07 Uboot链接地址 加载地址 和 链接脚本地址
  2. 锋利的jQuery-1-- :的用法
  3. ERP_Oracle Erp发展趋势基于SOA电子商务方案
  4. .net类库中和数据库相关的
  5. 【JSP】三种弹出对话框的用法实例
  6. js setTimeout深度递归后完成回调
  7. 设计模式之策略模式Strategy
  8. 学点bootstrap
  9. iOS适配:Masonry介绍与使用实践:快速上手Autolayout
  10. Java 高效 MVC &amp; REST 开发框架 JessMA v3.2.1 即将发布
  11. js中角度计算
  12. Linux驱动技术(八) _并发控制技术
  13. Redis之String
  14. linux 应用和发展
  15. bootstrap知识笔记
  16. ORM框架EF
  17. Docker部署HDFS
  18. Kaggle(2):验证和过分拟合
  19. 样条之Akima光滑插值函数
  20. Shiro系列(0) - 权限管理在J2EE企业级开发中的应用与实战

热门文章

  1. 【golang】kafka
  2. yii2 中excel表导出
  3. Forth相关IO操作
  4. 指导手册05:MapReduce编程入门
  5. 指导手册03:Hadoop基础操作
  6. ela的UNASSIGNED索引修复
  7. 实验 2:备份和还原IOS
  8. IntelliJ IDEA创建maven多模块项目
  9. ubuntu 菜单栏和终端都消失了,鼠标也成了一个&#215; 解决办法!!!
  10. 记录 spf13-vim 遇到的问题