随着网络的迅速发展,万维网成为大量信息的载体,如何有效地提取并利用这些信息成为一个巨大的挑战,网络爬虫应运而生。网络爬虫(又被称为网页蜘蛛、网络机器人),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。
本文主要介绍了网络爬虫的结构和应用、网络爬虫实现流程,以及 Python 实现 HTTP 请求等相关知识,是python爬虫的入门必修课。
网络爬虫按照系统结构和实现技术,大致可以分为以下几种类型:
通用网络爬虫:搜索引擎
聚焦网络爬虫:自动抓取特定目标
增量式网络爬虫:抓取新产生或发生更新的网页
深层网络爬虫:抓取深层网页
实际的网络爬虫系统通常是几种爬虫技术相结合实现的。
网络爬虫的基本流程如下:
通过上面的网络爬虫结构,我们可以看到读取 URL、下载网页是每一个爬虫程序都必备的,这就需要和HTTP 请求打交道。 Python中实现HTTP请求主要有3种方式:urllib2/urllib、httplib/urllib 以及 Requests。其中,Requests最为常用。
Requests 库是第三方模块,需要额外进行安装。Requests 是一个开源库,源码位于GitHub:https://github.com/kennethreitz/requests。可以使用pip命令进行安装,win+r,输入cmd,回车,输入安装命令 pip install requests,即可安装Requests模块。
python实现最简单的请求响应模型代码如下:
# GET请求
import requests
r = requests.get('http://www.baidu.com')
print(r.content)
# POST请求
import requests
postdata=['key':'value']
r = requests.post('http://www.xxxxxx.com/login',data=postdata)
print(r.content)
大家肯定见过类似这样的 URL::
https://blog.csdn.net/weixin_66026285?spm=1000.2115.3001.5343,就是在网址后面紧跟着“?”,“?”后面还有参数。那么这样的 GET 请求该如何发送呢?直接将完整的URL带入即可,不过Requests还提供了其他方式,示例如下:
import requests
url='https://blog.csdn.net/weixin_66026285?spm=1000.2115.3001.5343'
r=requests.get(url)
print(r.url)
url='https://blog.csdn.net/weixin_66026285'
postdata={'spm':'1000.2115.3001.5343'}
r=requests.get(url,postdata)
print(r.url)
通过打印结果,我们看到最终的 URL变成了:
https://blog.csdn.net/weixin_66026285?spm=1000.2115.3001.5343
import requests
url='http://www.baidu.com'
r = requests.get(url)
print('content-->'+str(r.content))
print('text-->'+str(r.text))
print ('encoding-->'+r.encoding)
r.encoding='utf-8'
print ('new text-->'+str(r.text))
print ('new encoding-->'+r.encoding)
其中r.content返回的是字节形式,r.text返回的是文本形式,r.encoding返回的是根据HTTP头猜测的网页编码格式。
Requests提供了中文乱码的解决方案,可以自行设置编码格式encoding为utf-8。
import requests
url='http://www.baidu.com'
user_agent ='Mozilla/4.0 (compatible;MSIE 5.5;Windows NT)'
headers={'User-Agent':user_agent}
r = requests.get(url,headers=headers)
print(r.content)
使用Requests模块进行请头的处理,只需在get()函数中以字典的形式添加headers参数即可。
import requests
url='http://www.baidu.com'
r = requests.get(url)
if r.status_code == requests.codes.ok:
#响应成功状态码为200
print (r.status_code)# 响应码
print (r.headers)# 响应头
print (r.headers.get('content-type'))# 推荐使用这种获取方式,获取其中的某个字段
print (r.headers['content-type'])# 不推荐使用这种获取方式
else:
r.raise_for_status()
获取响应码是可以使用Requests 中的status_code字段,获取响应头使用Requests 中的headers字段。headers包含所有的响应头信息,可以通过 get 函数获取其中的某一个字段,也可以通过字典引用的方式获取字典值,但是不推荐,因为如果字段中没有这个字段,第二种方式会抛出异常,第一种方式会返回 None。raise_for_status()函数当响应码是4XX或5XX时,抛出异常,而响应码为200时返回None。
获取Cookie字段的值
# 获取Cookie字段的值
import requests
url='http://www.baidu.com'
user_agent ='Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers={'User-Agent':user_agent}
r = requests.get(url,headers=headers)
# 遍历出所有的 cookie 字段的值
for cookie in r.cookies.keys() :
print (cookie+';'+r.cookies.get(cookie))
自定义Cookie字段的值
# 自定义Cookie字段的值
import requests
url='http://www.baidu.com'
user_agent ='Mozilla/4,0 (compatible; MSIE 5.5;Windows NT)'
headers={'User-Agent':user_agent}
cookies = {'id':'001','name':'momo'}
r= requests.get(url,headers=headers,cookies=cookies)
print (r.text)
自动处理Cookie
一般情况下,我们不需要关心Cookie值是多少,只是希望每次访问的时候,程序自动把Cookie的值带上。Requests 提供了一个session的概念,在连续访问网页,处理登录跳转时特别方便。
# session自动处理Cookie
import requests
loginUrl ='http://www.xxxxxxx.com/login'
s = requests.Session()
#首先访问登录界面,作为游客,服务器会先分配一个cookie
r = s.get(loginUrl,allow_redirects=True)
datas={'name':'your_username','pwd':'your_password'}
#向登录链接发送 post 请求,验证成功,游客权限转为会员权限
r = s.post(loginUrl,data=datas,allow_redirects= True)
print (r.text)
在使用python爬虫时,如果第一步访问的不是登录页面,而是直接向子链接发送Post 请求,由于访问登录界面时会分配一个Cookie,所以需要将这个Cookie 在发送 Post 请求时带上,才能成功访问。这种使用 Session 函数处理Cookie的方式十分常用。
处理重定向只需设置allow_redirects字段即可。设置为True是允许重定向,设置为False是禁止重定向。如果是允许重定向,可以通过history字段查看历史信息,即访问成功之前的所有请求跳转信息。
如下代码中,重定向的效果是访问百度时会将所有的HTTP请求全部重定向为HTTPS。
# 重定向与历史信息
import requests
url='http://www.baidu.com'
r = requests.get (url,allow_redirects=True)
print (r.url)
print (r.status_code)
print (r.history)
限定超时可以通过参数timeout设置。
# 超时设置
import requests
url='http://www.baidu.com'
r = requests.get (url,timeout=2)
print (r.url)
代理Proxy可以通过参数proxies配置单个请求。
# 代理设置
import requests
url='http://www.baidu.com'
proxies = {
"http":"http://111.225.152.191",
"https":"http://157.25.22.53"
}
r=requests.get(url,proxies=proxies)
print(r.url)
也可以通过环境变量HTTP_PROXY和HTTPS_PROXY来配置代理,使用 http://user:password@host/
的语法,但是这种方式在爬虫中很少用到。
推荐两个免费获取代理IP的网站(谨慎使用):
也可以通过环境变量HTTP_PROXY和HTTPS_PROXY来配置代理,使用 http://user:password@host/
的语法,但是这种方式在爬虫中很少用到。
推荐两个免费获取代理IP的网站(谨慎使用):