分类
根据应用的场景不同可分为通用爬虫和聚焦爬虫
通用爬虫
通用网络爬虫是捜索引擎抓取系统(Baidu、Yahoo等)的重要组成部分。主要目的是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份。
通用搜索引擎(Search Engine)工作原理
第一步:抓取网页
第二步:数据存储
第三步:预处理
第四步:提供检索服务,网站排名
通用性搜索引擎存在的局限性
1.通用搜索引擎对图片、数据库、音频、视频无能为力,不能很好地发现和获取。
2.通用搜索引擎大多提供基于关键字的检索,难以支持根据语义信息提出的查询。
聚焦爬虫
聚焦爬虫是为填补通用爬虫的不足而产生的。
补充
http:80/https:443
URL基本格式:scheme://host[:port#]/path/…/[?query-string][#anchor]
- scheme:协议(例如:http, https, ftp)
- host:服务器的IP地址或者域名
- port#:服务器的端口(如果是走协议默认端口,缺省端口80)
- path:访问资源的路径
- query-string:参数,发送给http服务器的数据
- anchor:锚(跳转到网页的指定锚点位置)
请求方法:HTTP 1.1中GET, POST 和 HEAD、OPTIONS, PUT, DELETE,TRACE 和 CONNECT。
常用的请求报头
- Host (主机和端口号)2. Connection (链接类型)3. Upgrade-Insecure-Requests (升级为HTTPS请求)4. User-Agent (浏览器名称)5. Accept (传输文件类型)6. Referer (页面跳转处)7. Accept-Encoding(文件编解码格式)8. Accept-Language(语言种类)9. Accept-Charset(字符编码)10. Cookie (Cookie)11. Content-Type (POST数据类型)
响应状态码
- 200 OK 请求成功
- 302 重定向
- 304 使用缓存资源
- 404 无法找到访问的资源
- 402 服务器拒绝访问,权限不够
- 500 服务器遇到不可知的问题(最有意思的~~)
Cookie 和 Session
Cookie :放在浏览器端的用于记住用户信息,缺点信息被暴漏出来了
Session:建立在Cookie之上的,放在服务器端的用于记录用户信息,缺点频繁的对服务器进行操作。
urllib2或urllib.request库的基本使用
urllib2.urlopen
向指定的url发送请求,并返回服务器响应的类文件对象,read方法读取,返回的对象类型为字符串
response = urllib2.urlopen("http://www.baidu.com")
Request和Header
执行更复杂的操作,比如增加HTTP报头,必须创建一个 Request 实例来作为urlopen()的参数;而需要访问的url地址则作为 Request 实例的参数
request = urllib2.Request(url, headers = header)
response = urllib2.urlopen(request)
补:也可使用add_header方法添加header
自定义Opener
通过 urllib2.build_opener()方法可支持代理和cookie等http/https的高级功能。使用自定义的opener对象,调用open()方法发送请求。
import urllib2
# 构建一个HTTPHandler 处理器对象,支持处理HTTP请求,同时开启Debug Log,debuglevel 值默认 0
http_handler = urllib2.HTTPHandler(debuglevel=1)
# 构建一个HTTPHSandler 处理器对象,支持处理HTTPS请求,同时开启Debug Log,debuglevel 值默认 0
# https_handler = urllib2.HTTPSHandler(debuglevel=1)
# 调用urllib2.build_opener()方法,创建支持处理HTTP请求的opener对象
opener = urllib2.build_opener(http_handler)
# 构建 Request请求
request = urllib2.Request("http://www.baidu.com/")
# 调用自定义opener对象的open()方法,发送request请求
response = opener.open(request)
# 获取服务器响应内容
print response.read()
ProxyHandler处理器(代理设置)
常见的爬虫和反爬手段,通过使用切换代理IP的方法,来应对网站针对同一IP在某一时段访问量过多而导致IP被封的情况。
import urllib2
import random
proxy_list = [
{"http" : "x.x.x.x:80"},
{"http" : "x.x.x.x:80"},
{"http" : "x.x.x.x:80"},
{"http" : "x.x.x.x:80"},
{"http" : "x.x.x.x:80"},
]
# 随机选择一个代理
proxy = random.choice(proxy_list)
# 使用选择的代理构建代理处理器对象
httpproxy_handler = urllib2.ProxyHandler(proxy)
opener = urllib2.build_opener(httpproxy_handler)
request = urllib2.Request("http://www.baidu.com/")
response = opener.open(request)
print response.read()
ProxyBasicAuthHandler(代理授权验证)
用于处理代理授权的身份验证,HTTPPasswordMgrWithDefaultRealm():来保存私密代理的用户密码,ProxyBasicAuthHandler():来处理代理的身份验证。
import urllib2
import urllib
# 私密代理授权的账户
user = "mr_mao_hacker"
# 私密代理授权的密码
passwd = "sffqry9r"
# 私密代理 IP
proxyserver = "61.158.163.130:16816"
# 1. 构建一个密码管理对象,用来保存需要处理的用户名和密码
passwdmgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
# 2. 添加账户信息,第一个参数realm是与远程服务器相关的域信息,一般没人管它都是写None,后面三个参数分别是 代理服务器、用户名、密码
passwdmgr.add_password(None, proxyserver, user, passwd)
# 3. 构建一个代理基础用户名/密码验证的ProxyBasicAuthHandler处理器对象,参数是创建的密码管理对象
# 注意,这里不再使用普通ProxyHandler类了
proxyauth_handler = urllib2.ProxyBasicAuthHandler(passwdmgr)
# 4. 通过 build_opener()方法使用这些代理Handler对象,创建自定义opener对象,参数包括构建的 proxy_handler 和 proxyauth_handler
opener = urllib2.build_opener(proxyauth_handler)
# 5. 构造Request 请求
request = urllib2.Request("http://www.baidu.com/")
# 6. 使用自定义opener发送请求
response = opener.open(request)
# 7. 打印响应内容
print response.read()
HTTPBasicAuthHandler处理器(Web客户端授权验证)
# 1. 构建一个密码管理对象,用来保存需要处理的用户名和密码
passwdmgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
# 2. 添加账户信息,第一个参数realm是与远程服务器相关的域信息,一般没人管它都是写None,后面三个参数分别是 Web服务器、用户名、密码
passwdmgr.add_password(None, webserver, user, passwd)
# 3. 构建一个HTTP基础用户名/密码验证的HTTPBasicAuthHandler处理器对象,参数是创建的密码管理对象
httpauth_handler = urllib2.HTTPBasicAuthHandler(passwdmgr)
# 4. 通过 build_opener()方法使用这些代理Handler对象,创建自定义opener对象,参数包括构建的 proxy_handler
opener = urllib2.build_opener(httpauth_handler)
# 5. 可以选择通过install_opener()方法定义opener为全局opener
urllib2.install_opener(opener)
# 6. 构建 Request对象
request = urllib2.Request("http://192.168.199.107")
# 7. 定义opener为全局opener后,可直接使用urlopen()发送请求
response = urllib2.urlopen(request)
# 8. 打印响应内容
print response.read()
异常错误处理
父类URLError和子类HTTPError
import urllib2
requset = urllib2.Request('https://www.jianshu.com/u/711615e5008a')
try:
urllib2.urlopen(requset)
except urllib2.HTTPError, err:
print err.code
except urllib2.URLError, err:
print err
else:
print "Good Job"