用 Python 编写网络爬虫 笔记

Chapter I 简介

为何要写爬虫?

  1. 每一个网站都应该提供 API,然而这是不可能的
  2. 即便提供了 API,每每也会限速,不如本身找接口

注意已知条件(robots.txt 和 sitemap.xml)

  1. robots.txt 中可能会有陷阱
  2. sitemap 中可能提供了重要的连接

估算网站的大小

一个简便方法是使用 site:example.com 查询,然而这种方法对于大战不适用css

识别网站所使用的技术

  1. builtwith 模块
    pip install builtwith
    builtwith.parse(url) # returns a dictpython

  2. python-whois 模块
    pip install python-whois
    import whois
    whois.whois(url)json

下载器

下载器须要提供的几个功能:浏览器

  1. 错误重试,仅当返回的错误为500的时候重试,通常400错误可认为不可恢复的网页
  2. 假装 UA
  3. 策略 a. 爬取站点地图 sitemap b. 经过 ID 遍历爬取
    i. ID 可能不是连续的,好比某条记录被删除了
    ii. ID 访问失效 n 次之后能够认为遍历彻底了
  4. 相对链接转化,这点能够利用 lxml 的 make_link_absolute 函数
  5. 处理 robots.txt 能够利用标准库的 robotsparser 模块
    import robotsparser
    rp = robotparser.RobotFileParser
    rp.set_url('path_to_robots.txt')
    rp.read()
    rp.can_fetch("UA", "url")
    True or False
  6. 支持代理
  7. 下载限速,粒度应该精确到每个站点比较好
  8. 避免爬虫陷阱,尤为是最后一页自身引用自身的例子 a. 记录连接深度

例子:https://bitbucket.org/wswp/code/src/chpter01/link_crawler3.py缓存

Chapter II 数据抓取

抽取资源的方式

  1. 正则
    不适用于匹配网页结构,由于网页结构中空白等都是可有可无的,而可能破坏正则 Structural-based
    适用于数据自己符合某种模式,好比 IP 地址,好比日期等 Content-based
  2. xpath 与 CSS
    适用于匹配网页的结构信息 Strctual-based,lxml 的 CSS 选择器在内部是转换为 xpath 实现的,css 远不如 xpath 灵活
  3. BeautifulSoup, 慢,历来没有在生产代码中见到过

下载的第二步,就是把得到的网页传递给 Extractor 来提取内容,能够经过传递给下载函数回调来处理,可是这种耦合性太强了cookie

Chapter III 下载缓存

书中的缓存把全部相应都作了缓存,包括500的错误响应,实际上这样的直接不缓存好了。。
书中的磁盘缓存把 url normalize 逻辑也加到了这里,感受比较混乱
注意使用磁盘文件缓存的话会受限于磁盘单目录文件的数量,即便是 ext4 文件系统也不大多线程

Chapter IV 并发下载

执行下载时间估算也是很重要的,每一个连接下载须要多长时间,整个过程须要多长时间
多线程的下载例子,手工模拟线程池并发

def process_queue(q):
    pass

threads = []
while thread or crawl_queue:
    for thread in threads:
        if not threads.is_alive():            threads.remove(thread)
    while len(threads) < max_threads and crawl_queue:
        thread = threading.Thread(target=process_queue, daemon=True)
        thread.start()
        threads.append(thread)
    time.sleep(some_time)

性能的增加与线程和进程的数量并非成线性比例的,而是对数比例,由于切换要花费必定的时间,再者最终是受限于带宽的app

Chapter V 动态内容

逆向接口

依赖于 Ajax 的网站看起来更复杂,可是实际上由于数据和表现层的分离会更简单,可是若是逆向工程也很差获得通用的方法,如何构建一个辅助工具呢?
表示出网页上哪些地方是动态加载的,列出 js 全局变量,列出可能的 jsonp 请求函数

利用 Ajax 接口时,能够利用各类边界状况,好比把搜索条件置为空,置为 *,置为 .

渲染动态网页

使用Qt
使用 Selenium 或者 PhantomJS,这时附加 Cookie 等都是很严重的问题

Chapter VI 表单交互

登陆表单中每每会有隐藏的参数,好比 form_key 用于避免表单重复提交,还可能须要 cookie 验证

Wow,居然能够直接从浏览器加载 Cookie,使用 browsercookie 模块

Chapter VII 验证码处理

使用机器识别验证码
使用 Pillow 和 pytesseract 识别验证码,可是 tessact 本不是用来识别验证码的

一种锐化方法

img.convert('L')
img.point(lambda x: 0 if x < 1 else 255, 'l')
tessact.image_to_string(img)

还能够经过限定字符集提升识别率

还可使用人工打码平台

相关文章
相关标签/搜索