用 Python 编写网络爬虫 笔记
Chapter I 简介
为什么要写爬虫?
- 每个网站都应该提供 API,然而这是不可能的
- 即使提供了 API,往往也会限速,不如自己找接口
注意已知条件(robots.txt 和 sitemap.xml)
- robots.txt 中可能会有陷阱
- sitemap 中可能提供了重要的链接
估算网站的大小
一个简便方法是使用 site:example.com 查询,然而这种方法对于大战不适用
识别网站所使用的技术
builtwith 模块
pip install builtwith
builtwith.parse(url) # returns a dictpython-whois 模块
pip install python-whois
import whois
whois.whois(url)
下载器
下载器需要提供的几个功能:
- 错误重试,仅当返回的错误为500的时候重试,一般400错误可认为不可恢复的网页
- 伪装 UA
- 策略
a. 爬取站点地图 sitemap
b. 通过 ID 遍历爬取
i. ID 可能不是连续的,比如某条记录被删除了
ii. ID 访问失效 n 次以后可以认为遍历完全了 - 相对连接转化,这点可以利用 lxml 的 make_link_absolute 函数
- 处理 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 - 支持代理
- 下载限速,粒度应该精确到每一个站点比较好
- 避免爬虫陷阱,尤其是最后一页自身引用自身的例子
a. 记录链接深度
例子:https://bitbucket.org/wswp/code/src/chpter01/link_crawler3.py
Chapter II 数据抓取
抽取资源的方式
- 正则
不适用于匹配网页结构,因为网页结构中空白等都是无关紧要的,而可能破坏正则 Structural-based
适用于数据本身符合某种模式,比如 IP 地址,比如日期等 Content-based - xpath 与 CSS
适用于匹配网页的结构信息 Strctual-based,lxml 的 CSS 选择器在内部是转换为 xpath 实现的,css 远不如 xpath 灵活 - BeautifulSoup, 慢,从来没有在生产代码中见到过
下载的第二步,就是把获得的网页传递给 Extractor 来提取内容,可以通过传递给下载函数回调来处理,但是这种耦合性太强了
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)
性能的增长与线程和进程的数量并不是成线性比例的,而是对数比例,因为切换要花费一定的时间,再者最终是受限于带宽的
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)
还可以通过限定字符集提高识别率
还可以使用人工打码平台
用 Python 编写网络爬虫 笔记的更多相关文章
- 利用Python编写网络爬虫下载文章
#coding: utf-8 #title..href... str0='blabla<a title="<论电影的七个元素>——关于我对电影的一些看法以及<后会无期 ...
- 读书笔记汇总 --- 用Python写网络爬虫
本系列记录并分享:学习利用Python写网络爬虫的过程. 书目信息 Link 书名: 用Python写网络爬虫 作者: [澳]理查德 劳森(Richard Lawson) 原版名称: web scra ...
- Python网络爬虫笔记(五):下载、分析京东P20销售数据
(一) 分析网页 下载下面这个链接的销售数据 https://item.jd.com/6733026.html#comment 1. 翻页的时候,谷歌F12的Network页签可以看到下面 ...
- Python即时网络爬虫项目启动说明
作为酷爱编程的老程序员,实在按耐不下这个冲动,Python真的是太火了,不断撩拨我的心. 我是对Python存有戒备之心的,想当年我基于Drupal做的系统,使用php语言,当语言升级了,推翻了老版本 ...
- Python即时网络爬虫:API说明
API说明——下载gsExtractor内容提取器 1,接口名称 下载内容提取器 2,接口说明 如果您想编写一个网络爬虫程序,您会发现大部分时间耗费在调测网页内容提取规则上,不讲正则表达式的语法如何怪 ...
- 用Python写网络爬虫 第二版
书籍介绍 书名:用 Python 写网络爬虫(第2版) 内容简介:本书包括网络爬虫的定义以及如何爬取网站,如何使用几种库从网页中抽取数据,如何通过缓存结果避免重复下载的问题,如何通过并行下载来加速数据 ...
- Java网络爬虫笔记
Java网络爬虫笔记 HttpClient来代替浏览器发起请求. select找到的是元素,也就是elements,你想要获取具体某一个属性的值,还是要用attr("")方法.标签 ...
- Python即时网络爬虫项目: 内容提取器的定义(Python2.7版本)
1. 项目背景 在Python即时网络爬虫项目启动说明中我们讨论一个数字:程序员浪费在调测内容提取规则上的时间太多了(见上图),从而我们发起了这个项目,把程序员从繁琐的调测规则中解放出来,投入到更高端 ...
- Python即时网络爬虫项目: 内容提取器的定义
1. 项目背景 在python 即时网络爬虫项目启动说明中我们讨论一个数字:程序员浪费在调测内容提取规则上的时间,从而我们发起了这个项目,把程序员从繁琐的调测规则中解放出来,投入到更高端的数据处理工作 ...
随机推荐
- 解决WebStorm无法连接到Chrome
问题: 点击 中的chrome时,出现了错误,如下: 解决办法: 找到 File>setting>Web Browser 修改为 C:\Program Files (x86)\Google ...
- js闭包深度讲解
js的闭包是学习js过程中的重点,但是不得不说也是一个难点呀,其涉及到了js中的很多概念.我在学习js中也遇到了很多问题,这篇文章算是一个对闭包的总结,文章主要内容为闭包的基本知识点与对其理解上的一些 ...
- JavaScript的基本规范
1.不要在同一行声明多个变量: 2.请使用===/!==来比较true/false或者数值: 3.使用对象字面量替代new Array这种形式: 4.Switch语句必须带有default分支: 5. ...
- Oh, my god令人头痛的“对象”--------C#数据类型
1.C#常用的数据类型: ①整型 int ②浮点型 float ③双精度型 double ④字符串 string ⑤布尔类型 ...
- android 透明状态栏方法及其适配键盘上推(一)
android的状态栏(statusBar)版本的差异化比较大.在android 4.4 以上和5.x可以设置状态栏背景颜色,但是不可以设置状态栏中字和图标的颜色.而系统默认的statusbar的字体 ...
- 解锁redis锁的正确姿势
解锁redis锁的正确姿势 redis是php的好朋友,在php写业务过程中,有时候会使用到锁的概念,同时只能有一个人可以操作某个行为.这个时候我们就要用到锁.锁的方式有好几种,php不能在内存中用锁 ...
- 自动部署Nginx和nfs并架设Nginx集群脚本
本人经过多次尝试,简单完成了自动部署Nginx和nfs脚本,并且能够自动部署web反向代理集群,下面详细的阐述一下本人的思路.(以下脚本本人处于初学阶段,写的并不是很完善,所以需要后期进行整理和修正, ...
- strtol函数 将字符串转换为相应进制的整数
转自http://hi.baidu.com/qwpsmile/blog/item/9bc44efa4f41018a9f514637.html +----------------+| strt ...
- 关于js参数传递矛盾新理解
之前看了很多人的解释,说js中,函数的参数传递都是值传递中不理解. 他们无非举了两个例子 在这两个例子中,第二个例子可以看出参数是由值传递的.因为函数内对象的变化没有影响到函数外对象的变化.但是在第一 ...
- centos 6.5 搭建JSP运行环境
一.安装nginx yum install nginx #安装nginx,根据提示,输入Y安装即可成功安装 service nginx start #启动 chkconfig nginx on #设为 ...