Bootstrap

爬虫技术系统性总结

准备系统地复习一遍爬虫,填填坑。

contents

  1. 1. 一:数据库的使用(mongoDB)

  2. 2. 二:python环境的安装

  3. 3. 三:PyMongo的使用

  4. 4. 四:正则表达式的应用一

  5. 5. 五:正则表达式的应用二

  6. 6. 六:网页内容解析

  7. 7. 七:网页内容选取神器XPath法

  8. 8. 八:多线程与常见算法

  9. 9. 九:动态网页的分析

  10. 10. 十:Cookie登录与post登录

  11. 11. 十一:常见反爬虫机制与应对方法

  12. 12. 十二:突破简单的验证码

  13. 12.1. 人工打码

  14. 12.2. 图象识别

  15. 13. 十三:Scrapy使用

  16. 13.1. Scrapy使用

  17. 13.2. 创建项目

  18. 13.3. 爬虫的运行

  19. 13.4. 最后来讲讲以前遗留的问题mongodb安装为windows服务

  20. 14. 十四:Scrapy与MongoDB

  21. 14.1. Scrapy的工程结构

  22. 14.2. Scrapy与MongoDB

  23. 14.3. 爬取数据

  24. 15. 十五:分布式爬虫的模型分析与创建

  25. 16. 十六:复杂的分布式爬虫

  26. 17. 十七:维护多个Session

  27. 17.1. 分布式爬虫的登录

  28. 17.2. Scrapy与Selenium

  29. 17.3. 验证码

一:数据库的使用(mongoDB)

1.什么是MongoDB?

MongoDB 是一款开源的文档数据库,并且是业内领先的 NoSQL 数据库,用 C++ 编写而成。

2.为什么要使用MongoDB数据库

MongoDB是非关系型数据库,MongoDB数据的储存形式和Python的字典非常的相似。

如下图所示:python爬虫系统学习一:数据库的使用,mongoDB

3.MongoDB 的安装

1)百度mongodb官网选择自己系统匹配的版本下载并安装

2)创建文件夹用来存放数据文件:D:\MongoDB\DB

3)在MongoDB的安装文件夹中,按住Shift键并点击鼠标右键,选择“在此处打开命令窗口”,然后输入以下代码启动MongoDB:

mongod.exe--dbpathD:\MongoDB\DB

4.图形化图形化管理工具-RoboMongo

简介:RoboMongo是一个跨平台的MongoDB管理工具。可以用来在图形界面中观察我们对MongoDB的修改是否生效。

安装以后,我们打开可以看到下图的栏目:

点击“Create”,如果MongoDB就在本地电脑上面运行,那就什么都不需要修改,直接点Save

回到图1的界面,点击“Connect”就可以联接MongoDB了。

二:python环境的安装

python安装

这里使用python2.7版本的环境

同样直接百度python官网下载自己系统对应版本的python解释器exe格式或msi格式都可以

注意:不要下载360软件管家提供的 python2.7.12rc1解释器此解释器无法使用pip安装第三方包

安装完成之后打开命令提示符 cmd 直接输入 python 如果安装成功则会出现如下提示

如果没有出现上图的提示则检查系统环境变量

参考 http://jingyan.baidu.com/article/48206aeafdcf2a216ad6b316.html

PyMongo 的简介及安装

1.什么是 PyMongo?

PyMongo模块是Python对MongoDB操作的接口包,代码主要实现对MongoDB的几种操作:增删改查以及排序等功能。

2.PyMongo 的安装

使用以下几种方法之一即可:

(1)直接使用pip 安装(推荐)

安装命令如下:

pip install pymongo 如果安装成功会显示pymongo包的版本号

(2)使用easy_install 安装

安装命令如下:

easy_install pymongo

由于众所周知的原因,pip 直接安装可能会遇到网络问题导致安装失败,因此,对于Windows下的同学,还可以访问:

http://www.lfd.uci.edu/~gohlke/pythonlibs/

在这个网站上找到pymongo,并下载whl包到本地,然后使用以下命令安装:

注意要下载与你python版本相符的pymongo包

pip install 下载下来的whl文件名

对于一些更复杂的安装情况,请访问MongoDB官网,查看完整的安装指导:

https://api.mongodb.com/python/current/installation.html

验证安装

请打开Python的交换环境,输入以下代码并回车,如果不报错,就表示安装成功:

import pymongo

PyMongo的使用

创建数据库

1

2

3

4

5

6

7

8

9

import pymongo

client = pymongo.MongoClient() 本地数据库不需要填写参数

database = client.person_info 创建名为person_info的数据库

col = database.people 在person_info数据库中创建people表

info_dict = {‘name’: ‘kingname’, ‘age’: 0, ‘sex’: ‘unknown’, ‘salary’: 888888}

col.insert(info_dict) 在表中插入数据

kingname = col.find()

for each in kingname:

print(each[‘salary’]) 查询数据

三:PyMongo的使用

导入模块

插入

MongoDB的插入操作非常简单。用到的方法为:insert(参数) ,插入的参数就是Python的字典。

1

2

data = {‘id’: 123, ‘name’: ‘ds’, ‘age’: 20, ‘salary’: 999999}

col.insert(data)

我们做爬虫,主要用MongoDB是来储存数据。所以主要使用的就是这个insert方法。

查找

MongoDB的查找功能对应的方法是:find(参数)和find_one(参数), 两个参数的类型均为Python字典,参数可以省略。其中,find_one()一次只返回一条信息。我们一般使用的最多的是find(参数)这个方法。

可以通过参数指定需要查找的内容。其中的参数可以省略不写。

1

2

content = col.find()

content = col.find({‘age’: 29})

第一行代码会返回你指定集合中的所有的内容。

第二行代码会返回所有年龄为29岁的人的记录。

这两种方式得到的结果content是一个pymongo对象,但是可以使用for循环展开。展开以后可以得到很多个字典。每个字典对应一条记录。

1

2

3

for row in content:

id = row[‘id’]

name = row[‘name’]

更新

更新用到的方法叫做update_one(参数1, 参数2)或者update_many(参数1,参数2), 前者只更新一条信息,后者更新所有符合要求的信息。这里的参数1,和参数2都是字典,都不能省略。请看代码:

1

2

col.update_one({‘age’: 20}, {’$set’:{‘name’: ‘kingname’}})

col.update_many({‘age’: 20}, {’$set’:{‘age’: 30}})

第一行代码的作用是,将第一个年龄为20岁的人的名字改为kingname。

第二行代码的作用是,将所有年龄为20岁的人的名字全部改为kingname。

删除

删除 用到的方法叫做delete_one(参数)或者delete_many(参数)这里的参数都是字典,不建议省略参数。delete_one(参数)只删除一条记录,delete_many(参数)删除所有的符合要求的记录。

1

2

col.delete_one({‘name’: ‘kingname’})

col.delete_many({‘name’: ‘kingname’})

第一行代码,删除第一个名字叫做kingname的人。

第二行代码,删除所有名字叫做kingname的人。

总结

我们在制作爬虫的过程中可能涉及到的PyMongo的知识主要就是这些。当然PyMongo还有一些其他的方法,如果大家有兴趣的话,可以查看PyMongo的官方文档:https://docs.mongodb.com/getting-started/python/client/

ORM 介绍

ORM(Object-relational mapping,对象关系映射),可以将对数据库的操作变为对象的操作。

MongoEngine就是MongoDB的一个ORM库,我们使用MongoEngine以后,就可以通过直接操作对象来控制MongoDB。

一般MongoEngine在基于Python的网页开发中应用较多。不过,在我们的爬虫上,也可以使用。

MongoEngine 的安装

使用pip 安装:pip install mongoengine

安装效果如下:

验证安装

打开python 交互环境,输入以下代码并回车,如果没有报错,则表示安装成功:

import mongoengine

MongoEngine 的使用

1.初始化连接

如果我们的MongoDB 是直接在本地电脑上面运行的,可以使用以下代码来连接到电脑上的MongoDB数据库:

1

2

from mongoengine import *

connect(‘数据库名’)

如果MongoDB不是运行在本地电脑上面的,就需要指定ip 地址和端口:

1

2

from mongoengine import *

connect(‘数据库名’, host=‘192.168.2.12’, port=3456) #请注意端口号是数字不是字符串

2.定义文档

定义一个类,这里我们以个人信息为例。这个类继承MongoEngine 的Document类。请注意,这里的类名People 对应了MongoDB中的集合名。类中的每一个变量,对应了每一条记录中的列名。

1

2

3

4

5

6

from mongoengine import *

class People(Document):

name = StringField(required=True) #请注意所有写了required=True的变量,在类初始化的时候都是必须填写的参数哦。

age = IntField(required=True)

sex = StringField(required=True)

salary = IntField() #这里的IntField 或者StringField 对应了数据类型

3.创建对象

初始化People类,创建一个对象:

1

2

kingname = People(name=‘kingname’, age=18, sex=‘male’, salary=99999) #注意这里的参数name, age 和sex是不可以省略的,但是salary可以省略

kingname.save()

当然,我们也可以这样写:

1

2

3

kingname = People(name=‘kingname’, age=18, sex=‘male’)

kingname.salary = 99999

kingname.save()

在信息已经保存以后,如果你想修改某个信息,你可以这样写:

1

2

kingname.age = 22

kingname.save()

这样就把年龄修改为22岁了。是不是比pymongo简单太多了?

4.读取对象

如果想读取所有的用户信息怎么办呢?非常简单:

1

2

3

4

for person in People.objects:

print(person.name)

print(person.age)

print(person.sex)

按条件搜索也非常简单,在People.objects后面加参数即可,例如搜索所有年龄为22岁的人:

1

2

for person in People.objects(age=22):

print(person.name)

你甚至会怀疑我到底是不是把这些信息写入到了数据库里面。你可以用RoboMongo读取一下数据库,看看是不是有一个集合叫做People,里面有我们添加进去的数据。

四:正则表达式的应用一

正则表达式介绍:

正则表达式(Regular Expression)是一段字符串,可以用来在一段文本中,查找,替换有规律的信息。

做一个比喻,假设在你的面前有一万个人,我让你去找一个人,他有如下特点:皮肤是绿色的,身高三米,内裤套在头上。那么只要这个人在这一万人中,你就能一眼找到他。如果我让你从这一万人中找十个有这种特征的人,你也可以在一瞬间把这十个人从这一万人中找出来。这个寻找的过程,在正则表达式中,叫做“匹配”。而你的大脑,天生就具有正则表达式的功能。

在计算机中,我们需要让计算机程序从一大段文本中找到我们需要的内容。就可以使用正则表达式来帮助我们。

使用正则表达式有如下步骤:

· 寻找规律

· 使用正则符号表示规律

· 提取信息

我们来举一个例子,下面有一段话:

今天天气不错,。password:88886666:password我刚刚不小心把我的密码写了出来。你能看到我的密码吗?

我发现我们都喜欢使用同样的密码,昨天我不小心看到了小红的密码password:11112222:password于是我用这个密码去入侵她的电脑,没想到成功了。

在她的电脑中,我发现了她的银行卡密码password:33334444:password于是我把她的银行卡密码也修改了。

在这一段文字中,一共出现了三个密码。这三个密码很有规律,他们都是 password:数字:password 这种形式的。那么,如果我可以有什么办法,能把符合 password:数字:password 这种格式的内容里面的数字提取出来,我就可以直接得到密码了。这就需要使用正则表达式来完成这个工作。

常用基本符号的基本意义:

.可以代表任意除\n以外的字符

一个点号代表一个字符 就是一个占位符

星号*表示匹配星号之前的0次或多次

问号?匹配前面的0次或1次

\\转义字符 不能单独使用 让有特殊意义的字符变成普通字符:\* 代表普通星号

让普通字符变成有意义的特殊字符\d代表数字

括号的使用

() 是为了提取匹配的字符串。当我们使用正则表达式提取内容的时候,可能只想提取部分内容,于是我们需要使用括号来标记我们需要的内容。

通过下面这个例子说明:

有一个字符串

1

2

3

4

a = Pythonpachong

B = re.findall (‘Pyth…chong’,a)

Print(B) 返回变量a的所有字符Pythonpachong

B = re.findall (‘Pyth(…)chong’,a)

加上括号之后 只返回 onpa

提取数字

正则表达式里面,使用 \d 来表示一位数字。这里要强调一下,\d 虽然是由从左上向右下的斜杠和字母d构成的,但是我们要把\d看成是一个正则表达式符号整体。从左上向右下的斜杠,名字叫做“反斜杠”,在正则表达式中是作为转义字符,不能单独使用。

如果要提取两个数字,我们可以使用 \d\d,如果要提取三个数字,我们可以使用\d\d\d,但是问题来了,如果我们不知道有这个数有多少位怎么办呢?就需要使用上一课讲到的+号。+ 号可以匹配它前面的符号一次或者多次。所以使用 \d+,可以表示一个任意位数的数字。

我们的密码是123455677,请记住它。

当我们对这一段文字使用(\d+)的时候的时候,就会把123455677给提取出来。

提取文本

对于文本来说,我们在爬虫中一般使用 .*? 这三个符号来完成。

我们知道点号表示任意非换行符的字符,*号表示匹配它前面的字符零次或者任意多次。所以 .* 表示匹配一串任意长度的字符串任意次。这个时候必须在.* 的前后加其他的符号来限定范围,否则得到的结果就是原来的整个字符串。

如果在 .* 的后面加一个问号变成 .*? ,那么可以得到什么样的结果呢?问号表示匹配它前面的符号0次或者1次。于是 .*? 的意思就是,匹配一个能满足要求的最短字符串。

提取多行文本

只需把文本匹配模式中加入\n:.*?\n.*?

· .* 外号贪心算法,获取最长的满足条件的字符串

匹配字符串中所有满足条件的内容

.*? 外号非贪心算法,获取最短的能满足条件的字符串

只匹配一个满足条件的内容后退出

五:正则表达式的应用二

导入模块

Python的正则表达式模块名字为 re ,我们可以使用:import re来导入并使用。

findall 方法

Python的正则表达式模块包含一个findall方法,它可以以列表的形式返回所有满足要求的字符串

findall的函数原型为:

re.findall(正则规则, 内容, [flag=0])

findall的结果是一个列表,包含了所有的匹配到的结果

当我们需要提取某些内容的时候,需要使用小括号将这些内容括起来,这样才不会得到不相干的信息。如前文所说的一样

函数原型中,最后一个参数是可以省略的。当不省略的时候,可以起到一些辅助功能。例如忽略大小写,忽略换行符等等。我们这里以忽略换行符为例来进行说明,请看下图:

当我们抓取网页的时候,非常容易出现这样的情况,我们要匹配的内容中存在换行符\n,这种情况下,要忽略换行符,就需要使用到re.S这个flag. 我们对比上图的结果,就会发现flags的作用。虽然说匹配到的结果中出现了\n 这个符号,不过我们后期清洗数据的时候把它替换掉即可。

search 的使用

search方法可以返回第一个满足要求的字符串。一旦找到符合要求的内容,它就会停止查找。

search的函数原型为:

re.search(正则, 内容, flags=0)

search的结果是一个正则表达式的对

;