Python爬虫原理与常用模块——urllib与反爬策略

1 http协议

1.1 简介

1.HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web)服务器传输超文本到本地浏览器的传送协议。

2.HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。

1.2 工作原理

  1. HTTP协议工作于客户端-服务端架构上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。

  2. Web服务器有:Apache服务器,IIS服务器(Internet Information Services)等。

  3. Web服务器根据接收到的请求后,向客户端发送响应信息。

  4. HTTP默认端口号为80,但是你也可以改为8080或者其他端口。

HTTP三点注意事项:

  1. HTTP是无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

  2. HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。

  3. HTTP是无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

  4. 以下图表展示了HTTP协议通信流程:

1.3 参数详解

关键字说明
Request URL请求的URL地址
Request Method请求方法
Status Code状态码
Remote Address远端地址
Connection连接类型
Content-Encoding数据压缩方式 常用压缩算法: Content-Encoding:gzip Content-Encoding:compress Content-Encoding:deflate Content-Encoding:identity Content-Encoding:br
Content-Type互联网媒体类型 text/html HTML格式 text/plain: 文本格式 text/xml: XML格式 image/gif: gif图片格式 image/jpeg: jpg图片格式 image/png: png图片格式 application/xhtml+xml: XHTML格式 application/xml:XML数据格式 application/atom+xml Atom XML聚合格式 application/json JSON数据格式 application/pdf: pdf格式 application/msword: Word文档格式 application/octet-stream 二进制流数据(例如文件下载)application/x-www-form-urlencoded: 普通表单提交 multipart/form-data 表单文件上传
Accept发送端希望接受的数据类型
text()文本内容
User-AgentAgent 用户代理
Accept-Encoding发送端支持的压缩算法
CookieCookie
Accept-Language发送端支持的语言
Cache-Control缓存机制

2 网络基础爬虫

2.1 简介

  1. 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。

  2. 其实通俗的讲就是通过程序去获取web页面上自己想要的数据,也就是自动抓取数据

2.2 用途

可以抓取到 任何你想要抓取的内容,前提是你的浏览器访问得到,

2.3 本质

爬虫的本质就是模拟浏览器打开网页,获取网页中我们想要的那部分数据。

浏览器打开网页的过程:

1、在浏览器的输入地址栏,输入想要访问的网址。

2、经过DNS服务器找到服务器主机,向服务器发送一个请求

3、服务器经过解析处理后返回给用户结果(包括html,js,css文件等等内容)

4、浏览器接收到结果,进行解释通过浏览器屏幕呈现给用户结果

上面我们说了爬虫的本质就是模拟浏览器自动向服务器发送请求,获取、处理并解析结果的自动化程序。

爬虫的关键点:模拟请求,解析处理,自动化。

2.4 基本流程

2.4.1 发起请求

通过HTTP库向目标站点发起请求(request),请求可以包含额外的header等信息,等待服务器响应

2.4.2获取响应内容

如果服务器能正常响应,会得到一个Response,Response的内容便是所要获取的页面内容,类型可能是HTML,Json字符串,二进制数据(图片或者视频)等类型

2.4.3 解析内容

得到的内容可能是HTML,可以用正则表达式,页面解析库进行解析,可能是Json,可以直接转换为Json对象解析,可能是二进制数据,可以做保存或者进一步的处理

2.4.4 保存数据

保存形式多样,可以存为文本,也可以保存到数据库,或者保存特定格式的文件

2.5 urllib

2.5.1简介

  1. 在Python2版本中,有urllib和urlib2两个库可以用来实现request的发送。

  2. 而在Python3中,已经不存在urllib2这个库了,统一为urllib。

  3. Python3 urllib库官方链接:https://docs.python.org/3/library/urllib.html

  4. 常用模块:

    • urllib.request打开和浏览url中内容

    • urllib.parse解析url

2.5.2 urllib.request

2.5.2.1 简介

urllib.request 模块提供了最基本的构造 HTTP请求方法,可以模拟浏览器的一个请求发起过程。同时它还带有处理authenticaton(授权验证),redirections(重定向),cookies(浏览器Cookies)以及其它内容。

2.5.2.2 urllib.request.urlopen()

1.格式

urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None,capath=None, cadefault=False, context=None)

2.参数详解

参数说明
data可选附加参数 字节流编码格式(bytes() 可转换) 请求方式会变为POST
timeout(超时时间)单位为秒,若请求超出了设置时间还没有响应,则抛异常
response.read()得到返回的网页内容,可使用decode(“utf-8”)解码字符串
response.status得到返回结果的状态码, 200代表请求成功, 404代表网页未找到

注: 返回HTTPResposne类型的对象

2.5.2.3 urllib.request.Request

  1. 简介

利用urlopen()方法可以实现最基本的请求发起,但这几个简单的参数并不足以构建一个完整的请求。使用强大的Request类可以在请求中加入需要的headers等信息。

  1. 格式
urllib.request.Request(url, data = None, headers = {},origin_req_host = None, unverifiable = False, method = None)
  1. 参数
参数说明
url请求网页的链接,是必传参数
data必须传 bytes (字节流)类型的数据, 如果是一个字典,可以先用 urllib.parse.urlencode() 编码。
headers字典类型, 可以在构造 Request 时通过 headers 参数传递,也可以通过调用 Request 对象的 add_header() 方法来添加请求头。
origin_req_host请求方的 host 名称或者 IP 地址。
unverifiable判断请求是否是无法验证的,默认是 False 。意思就是说用户没有足够权限来选择接收这个请求的结果
method字符串类型, 用来指示请求使用的方法,比如 GET , POST

2.6 request请求

2.6.1 get请求

2.6.1.1 简介

未指定mothod的参数的请求,默认就是get请求

2.6.1.2 实例

import urllib.request as ur 
request = ur.Request('https://edu.csdn.net/') 
response = ur.urlopen(request).read() 
print(response)

2.6.2 post请求

2.6.2.1 简介

使用method=’post’方式来指定 请求方式,一般用于表单的信息提交.

2.6.2.2 实例

import urllib.request as ur 
import urllib.parse as up 
import json 
word = input('请输入要翻译的中文') 
data = {'kw':word} 
data_url = up.urlencode(data) 
request = ur.Request(url='https://fanyi.baidu.com/sug',data=data_url.encode('utf-8')) response = ur.urlopen(request).read() 

print(response) ret = json.loads(response) 
print(ret) translate = ret['data'][0]['v'] print(translate) 

#以上代码运行结果: 
请输入要翻译的中文smart 
adj. 衣冠楚楚的; 衣着讲究的; 整洁而漂亮的; 光鲜的; 聪明的; 机敏的; 精明的;

2.7 url编码与解码

2.7.1 简介

urllib.parse.urlencode,对data参数的内容进行编码

urllib.parse.unquote,对data参数的内容进行解码

2.7.2 实例

import urllib.parse as up 
import urllib.request as ur 
kw = '动漫' 
data = {'kw':kw,'ie':'utf-8','pn':'100'} 
data_url = up.urlencode(data) 
print(data_url) 

ret = up.unquote(data_url) 
print(ret) 

request = ur.Request('https://tieba.baidu.com/f?'+data_url) 
response = ur.urlopen(request).read() 

#运行结果:
kw=%E5%8A%A8%E6%BC%AB&ie=utf-8&pn=100 
kw=动漫&ie=utf-8&pn=100

3 Hader伪装与模拟登陆

3.1 简介

  1. Header伪装:

    爬取一些网页时,会出现403错误,这表示这些网页防止别人恶意采集其信息所以进行了一些反爬虫设置。可以设置一些Headers信息,模拟成浏览器去访问这些网站,此时就能解决这个问题

  2. 模拟登陆(维持登录状态):

    HTTP是一个无状态协议,但是在访问网页时,有时我们需要保存会话信息,比如登录信息。

有两种比较常用的保存会话信息的方式:Cookie及Session

  • 使用Cookie会将所有会话信息保存在客户端
  • 使用Session会将会话信息保存在服务器端,但是服务器端会给客户端发SessionID等信息,这些信息一般存在客户端的Cookie中

有了Cookie,当我们登录成功后,爬取该网站的其他网页时,则会保存登录状态进行内容的爬取

3.2 参数分析

  1. User-Agent : 请求中必须要携带的一个参数

  2. cookie: 若需要抓取登录后才能拿到信息的网站时,需要用到cookie.

3.3 引用方式

import user_agent 
# 引入, user_agent.get_user_agent_pc() 
# 调用方法,随机选择一个User-Agent. 

3.4 Cookie的获取方式

1.使用无痕的谷歌浏览器访问url.

2.*network—>找到请求的接口—> request headers中拿到cookie的值

3.5 实例

import urllib.request as ur
import user_agent 
import lxml.etree as le

request = ur.Request(
    url='https://edu.csdn.net/mycollege',
    headers={ 'User-Agent':user_agent.get_user_agent_pc(), 'Cookie':'获取到实时cookie的值',}
)
response = ur.urlopen(request).read().decode('utf-8')
html_x = le.HTML(response)
title_s =html_x.xpath('//li[@class="item_box"]//h1/a/text()')
print(title_s)

4 ip代理的使用

4.1 为什么要使用代理ip

网站为了防止被爬取,会有反爬机制,对于同一个IP地址的大量同类型的访问,会封锁IP,过一段时间后,才能继续访问,这个时候就需要我们用代理ip去构建请求,防止网站的反爬,也就是俗称的反反爬.

4.2 反爬策略

反爬策略
检测浏览器header, User-Agent
ip 封禁
图片验证码
滑块
JS轨迹
证书加密
AI识别

4.3 应对方式

应对方式
建立代理IP, 轮换访问
设置访问时间间隔
可动态设置user agent
禁用cookies
设置延迟下载
使用IP地址池(代理IP、VPN等)

4.4 实例

#http://api.ip.data5u.com/dynamic/get.html?order=d314e5e5e19b0dfd19762f98308114ba&sep=4 是代理的获取接口,在这里推荐使用无忧代理. 
import urllib.request as ur 

proxy_address=ur.urlopen('http://api.ip.data5u.com/dynamic/get.html?order=d314e5e5e19b0dfd19762f98308114ba&sep=4').read().decode('utf-8').strip() 

print(proxy_address) 
# 创建proxy_handler 
proxy_handler = ur.ProxyHandler({'http':proxy_address}) 

# 新建opener对象 
proxy_opener = ur.build_opener(proxy_handler) 
request = ur.Request(url='https://edu.csdn.net/') 
reponse = proxy_opener.open(request).read() 

print(reponse) 
# 注: 代码中的ip提取接口在使用时记得更换. 
©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页