两种典型爬虫:通用网络爬虫、聚焦网络爬虫
通用网络爬虫实现原理与过程:
- 获取初始的URL
- 根据初始的URL爬取页面并获取新的URL
- 将新的URL放到URL队列中
- 从URL队列中读取新的URL,并根据新的URL爬取网页,同时从新网页中获取新的URL,并重复上述爬取过程
- 满足爬虫系统设置的停止条件时,停止爬取
聚焦网络爬虫(有目的地进行爬取)实现原理与过程:
定义和描述要爬取的目标
获取初始的URL
根据初始的URL爬取页面并获取新的URL
从新的URL中过滤掉与爬取目标无关的链接,同时将已爬取的URL地址存放到一个URL列表中,用于去重和判断爬取的进程
将过滤后的链接放到URL队列中从URL队列中,根据搜索算法,确定URL的优先级,并确定下一步要爬取的URL地址
从下一步要爬取的URL地址中,读取新的URL,然后依据新的URL地址爬取网页,并重复上述爬取过程
-
满足系统中设置的停止条件,或无法获取新的URL地址时,停止爬行
爬行策略主要有深度优先、广度优先、最佳优先等爬行策略。
身份识别
一般的,爬虫对网页进行爬取的时候,会通过HTTP请求中的User Agent字段告知自己的身份信息。一般爬虫访问一个网站的时候,首先会根据该站点下的Robots.txt文件来确定可以爬取的网页范围,Robots协议是需要网络爬虫共同遵守的协议,对于一些禁止的URL地址,网络爬虫则不应该爬取访问。
爬虫方法
本篇笔记主要记录利用python爬取数据时最常用的两个方法库:Requests库和Scrapy库。
Requests
#常用的模版:
import requests
url = ''
def geturl(url):
try:
r = requests.get(url,timeout = 10)
r.raise_for_status()
r.encoding = r.apparent_encoding
print(r.text[:1000])//return r.text[:1000]
except:
print('error')
Requests主要方法
# 常用命令:
requests.get()
requests.head() #当网页比较大的时候,先获取它的头部信息
# 一般用法:
requests.get/head('网址',**kwargs)
kv = 字典
params = kv #用于网址?后面添加内容
headers = kv #用于改变爬虫的user-agent
timeout = 10
Requests属性
r.content #用于当要以二进制形式存储的时候
Re库的基本使用
import re #主要用于字符串匹配
re库主要使用raw string类型(原生字符串类型)
如:r'[1-9],{5}'
原生字符串即不包含转义符的字符串.
Re库主要功能函数
函数 | 说明 |
---|---|
re.seach() | 在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象. |
re.match() | 从一个字符串的开始位置起匹配正则表达式,返回match对象. |
re.findall() | 搜索字符串,以列表类型返回全部能匹配的字符串. |
re.split() | 将一个字符串按照正则表达式结果进行分割,返回列表类型. |
re.finditer() | 搜索字符串,返回一个匹配结果的迭代类型,每一个迭代元素是match对象. |
re.sub() | 在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串. |
re.search(pattern,string,flags=0)
- pattern:正则表达式的字符串或原生字符串表示
- string:待匹配字符串
- flags:正则表达式使用的控制标记
常用标记 | 说明 |
---|---|
re.I re.IGNORECASE | 忽略正则表达式的大小写,[A-Z]能够匹配小写字符 |
re.M re.MULTILINE | 正则表达式中的^操作符能够将给定字符串的每行当作匹配开始 |
re.S re.DOTALL | 正则表达式中的.操作符能够匹配所有字符,默认匹配所有除换行符外的所有字符 |
import re
match=re.search(r'[1-9]\d{5}','BIT100081')
if match:
print(match.group(0))
#输出 100081
type(match)#输出 _sre.SRE_Match
match就是一次匹配的结果.
match对象的属性 | 说明 |
---|---|
.string | 待匹配的文本 |
.re | 匹配时使用的pattern对象(正则表达式) |
.pos | 正则表达式搜索文本的开始位置 |
.endpos | 正则表达式搜索文本的将结束为止 |
match对象的方法 | 说明 |
---|---|
.group(0) | 获得匹配后的字符串 |
.start() | 匹配字符串在原始字符串的开始位置 |
.end() | 匹配字符串在原始字符串的结束为止 |
.span() | 返回(.start(),.end()) |
Re库默认采用贪婪匹配,即输出匹配最长的子串.
match=re.search(r'PY.*N','PYANBNCNDN')
match.group(0)
#贪婪匹配,输出PYANBNCNDN
match=re.search(r'PY.*?N','PYANBNCNDN')#加?号后,为最小匹配,输出PYAN
match.group(0)
最小匹配操作符 | 使用说明 |
---|---|
*? | 前一个字符0次或无限次扩展,最小匹配 |
+? | 前一个字符1次或无限次扩展,最小匹配 |
?? | 前一个字符0次或1次扩展,最小匹配 |
{m,n}? | 扩展前一个字符m至n次(含n),最小匹配 |
事实上,操作符后加"?",就可以获得匹配结果.
Scrapy
常用命令
scrapy startproject name cd name scrapy genspider sname #创建工程,spider模版
编写spider里的.py内容 #进行内容爬取和信息处理 #def parse就是对get到的Response进行处理
编写pipelines.py文件 #对所得到的信息做进一步处理
修改setting.py #对爬虫的性能做进一步优化
-
scrapy crawl name #运行爬虫
爬虫中的注意点
对于url网址,不必在意里面一些复杂的内容,可以直接忽略,找几个网址的共同点
获取到html信息后,可以用beautifulsoup进行形式解析处理;也可以直接进行搜索+re
eval()#可以去引号
url里必须都是字符串形式
-
正则表达式中“两者选其一并且可无限扩充”用
[abc]*
不要拘泥于一个信息源(一个网站),选择最合适爬虫的网站
只要是在爬取时、循环时一定要异常处理!
如果返回值是列表,而且只有一个元素或者有了特定要选取的元素。可以直接在后面添加[0]