爬虫的基础了解及应用

一、爬床基础

1、安装虚拟指令介绍

#安装虚拟环境(window下加-win,苹果系统不需要加)
pip install virtualenvwrapper-win
#常用命令
mkvirtualenv pmz(创建虚拟环境的名字)				 	 #创建虚拟环境成功后会自动切换到环境下
workon envname(envname(切换虚拟环境的名字)) 		  	  #切换到虚拟环境
pip list     										#查看虚拟安装所有的包
deactivate   										#退出虚拟环境
rmvirtualenv pmz(pmz(删除虚拟环境))               	#删除虚拟环境
lsvirtualenv  										#列出所有已创建的虚拟环境
mkvirtualenv--python--C: ..python.exe envname   	#指定Python解释器创建虚拟环境

2、爬虫概念

爬虫, 又称网页蜘蛛或网络机器人. 
爬虫是 模拟人操作客户端(浏览器, APP) 向服务器发起网络请求,
 抓取数据的自动化程序或脚本. (*****) 
# 说明: 
	1.模拟: 用爬虫程序伪装出人的行为, 避免被服务识别为爬虫程序 
    2.客户端: 浏览器, APP都可以实现人与服务器之间的交互行为, 应用客户端从服务器获取数据 
    3.自动化: 数据量较小时可以人工获取数据, 但往往在公司中爬取的数据量在百万条, 千万条级别的, 所以要程序		自动化获取数据.
cpython   -   Ipython
#通用爬虫----只是爬虫,为搜索引擎提供检索服务
1.起始url
2.url队列    --------爬取数据


#设计思路
1.确定url,发起请求,获取响应
2.数据解析:re,正则,xpath,Bs4,pyQuery
3.数据持久化:    数据库Mysql   Redisa,MongoDB

3、爬虫分类

(1): 通用爬虫-----只是爬虫,为搜索引擎提供检索服务:搜索引擎
    # 实例: 百度, 搜狗, Google的搜索引擎 
    # 功能: 访问网页 -> 抓取数据 -> 数据处理 -> 提供检索服务 
    # 工作流:
    	1.给定一个起始URL, 存于爬取队列中 
        2.爬虫程序从队列中取出url, 爬取数据 
        3.解析爬取数据, 获取网页内的所有url, 放入爬取队列
        4.重复第二个步骤
    # 使搜索引擎获取网站链接: 
    	1.主动将url提交给搜索引擎(https://ziyuan.baidu.com/linksubmit/url) 
        2.在其他热门网站设置友情了解 
        3.百度和DNS服务商合作, 收录新网站
    # 网站排名(SEO): 
    	1.根据PageRank值进行排名(流量, 点击率) 
        2.百度竞价排名, 钱多就靠前排 
    # 缺点: 
    	1.抓取的内容多数无用 
        2.无法精确获取数据 
    # 协议: robots协议 --> 约定哪些内容允许哪些爬虫抓取 
    (约束通用爬虫和聚焦爬虫)
    	1.无需遵守, 该协议适用于通用爬虫, 而我们写的是聚焦爬虫 
        2.查看方法: 网站url/robots.txt, 如https://www.baidu.com/robots.txt
(2): 聚焦爬虫-----聚焦爬虫
    # 概念:
    	聚焦爬虫指针对某一领域根据特定要求实现的爬虫程序,
    	 抓取需要的数据(垂直领域爬取)
    # 设计思路: 
    	(1).确定爬取的url, 模拟浏览器请服务器发送请求  
        (2).获取响应数据并进行数据解析 ---re,正则,[xpath]推荐,Bs4,pyQuery
        (3).将目标数据持久化到本地----- .MySQL,MongoDB,Redis

4、协议模型

OSI七层模型
7.应用层   6.表示层   5.会话层   4.传输层    3.网络层    2.数据链路层    1.物理层 (从下往上数)
tcp 五层协议
    1.应用层:http/Https/ftp/ssh
    2.传输层:tcp/udp
    3.网络层: ip协议
    4.数据链路层:arp协议
    5.物理层:以太网协议
    

5、HTTP协议与HTTP S协议

# HTTP协议: 明文传输, 端口80 
- Http协议, 全称为Hyper Text Transfer Protocol, 即超文本传输协议. 
- HTTP协议是用于从网络传输超文本数据到本地浏览器的传送协议,
-  它能保证高效而准确地传送超文本文档. 
- 目前广泛使用的是HTTP 1.1版本     

# HTTPS协议: 加密传输, 端口443 
- HTTPS全称是Hyper Text Transfer Protocol over Secure Socket Layer,
-  是以安全为目标的 HTTP通道. HTTPS协议实质是HTTP的安全版, 
- 即HTTP下加入SSL安全套接层, 简称HTTPS. 
- HTTPS的安全体现在SSL的加密行为, 即通过HTTPS协议传输的数据都是经过SSL加密的 
- HTTPS的作用: 
   1.建立一个信息安全的通道来保证数据传输的安全 
   2.确认网站的真实性, 凡是使用了HTTPS的网站, 都可以通过点击浏览器
   地址栏的锁头标志来查看网站 认证之后的真实信息, 
   也可以通过CA机构颁发的安全签章来查询 
   
# HTTP与HTTPS协议的区别:(背下来) 
   1)、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。 
   2)、http是超文本传输协议,信息是明文传输,https则是具有安全性的
   ssl加密传输协议。 
   3)、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,
   后者是443。 
   4)、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的
   可进行加密传输、身份认证的网络协议,比http协议安全。

6、TCP与UDP 协议

# TCP与UDP 
1.TCP协议:是一种面向连接的, 可靠的, 基于字节流的传输层通信协议 
   1).有序性: 数据包编号, 判断数据包的正确次序 
   2).正确性: 使用checksum函数检查数据包是否损坏, 发送接收时都会计算校验和 
   3).可靠性: 发送端有超时重发, 并由确认机制识别错误和数据的丢失 
   4).可控性: 滑动窗口协议与拥塞控制算法控制数据包的发送速度 
       
2.UDP协议: 用户数据报协议, 面向无连接的传输层协议, 传输不可靠. 
   1).无连接, 数据可能丢失或损坏 
   2).报文小, 传输速度快 
   3).吞吐量大的网络传输, 可以在一定程度上承受数据丢失

# ARP协议: 通过IP获取目标计算机mac地址的协议(通过IP找mac)

7、服务器常见端口

1.ftp: File Transfer Protocol的缩写, 即文件传输协议. 端口:21 
2.ssh: Secure Shell的缩写, 用于远程登录会话. 端口:22 
3.MySQL: 关系型数据库, 端口:3306
4.MongoDB: 非关系型数据库, 端口:27017 
5.Redis: 非关系型数据库, 端口:6379

8、开发准备

# web端

1. Python3.6 
2. Pycharm 
3. Google Chrome

#抓包工具
fiddler抓包工具

二、爬虫实践

1、第一次爬虫

# b---->代表bytes----->字节类型
# encode()  编码
# decode()  解码   utf-8(国际通用码)   gbk(国标库)    gb2312(国标2312)

'''
#文件使用方式标识
w ---  写,会覆盖所有   r ---读  a --- 写,在末尾追加
wb,rb,ab-------二进制写,读
w+ ---读写,r+读写,区别在于文件不存在,不会创建新文件
'r':默认值,表示从文件读取数据。
'w':表示要向文件写入数据,并截断以前的内容
'a':表示要向文件写入数据,添加到当前内容尾部
'r+':表示对文件进行可读写操作(删除以前的所有数据)
'r+a':表示对文件可进行读写操作(添加到当前文件尾部)
'b':表示要读写二进制数据
'''
# *args: 动态位置传参
# **kwargs: 动态关键字传参

import requests

'''爬取百度首页'''

# 1.确定url, 向服务器发起请求, 获取响应数据
url = 'https://www.baidu.com/'  
res = requests.get(url=url)
# 2.解析数据(略过)
res.encoding = 'utf-8'
print(res.text)
# 3.持久化到本地: 写文件, MySQL, redis, MongoDB
# f = open('baidu.html', 'w', encoding='utf-8')
# f.write(res.text)
# f.close()
with open('baidu.html', 'w', encoding='utf-8') as f:
    f.write(res.text)
print('执行此行代码前就关闭了文件')

2、八大请求方式

# 请求: 有客户端向服务器发出的, 可以分为四部分内容: 
	1.请求方法(Request Method), 
    2.请求网址 (Request URL), 
    3.请求头(Request Headers),   #  ******
    4.请求体(Request Body)       #  ******
# 请求方法:常见有8种 (***背会***)
	- GET: 请求页面, 并返回页面内容(**获取**) #重点 
    - POST: 用于提交表单数据或上传文件, 数据包含在请求体中 # 重点 
    - PUT: 从客户端向服务器传送的数据取代指定文档中的内容 
    - DELETE: 请求服务器删除指定的页面 
    - HEAD: 类似于GET请求,只不过返回的响应中没有具体的内容,用于获取报头 
    - CONNECT: 把服务器当作跳板,让服务器代替客户端访问其他网页 
    - OPTIONS: 允许客户端查看服务器的性能 
    - TRACE: 回显服务器收到的请求,主要用于测试或诊断 
************
# 中点掌握GET & POST: GET与POST的区别(重点) --> **(面试出镜率较高)** 
	1.GET请求中的参数包含在URL里面, 数据可以在URL中看到, 而POST请求的URL不会包含这些数据, POST的数据都是通过表单形式传输的, 会包含在请求体中 
    2.GET请求提交的数据最多只有1024字节, 而POST方式没有限制

3、请求头简介

# 请求头: 
请求头,用来说明服务器要使用的附加信息. 重点掌握: ***Accept, Cookie, Referer, User-Agent***       
1.Accept:请求报头域,用于指定客户端可接受哪些类型的信息 # 重点(*/*) 
    2.Cookie:也常用复数形式 Cookies,这是网站为了辨别用户进行会话
    跟踪而存储在用户本地的数据。它 的主要功能是维持当前访问会话。
    例如,我们输入用户名和密码成功登录某个网站后,
    服务器会用会话保存登 录状态信息,后面我们每次刷新或请求该站点的其他页面时,
    会发现都是登录状态,这就是Cookies的功劳。 Cookies里有信息标识了
    我们所对应的服务器的会话,每次浏览器在请求该站点的页面时,
    都会在请求头中加 上Cookies并将其发送给服务器,服务器通过Cookies
    识别出是我们自己,并且查出当前状态是登录状态,所 以返回结果就是
    登录之后才能看到的网页内容 # 重点 
    3.Referer:此内容用来标识这个请求是从哪个页面发过来的,
    服务器可以拿到这一信息并做相应的处理,
    如 作来源统计、防盗链处理等 # 重点 
    ***********************************************
    4.User-Agent:简称UA,它是一个特殊的字符串头,
    可以使服务器识别客户使用的操作系统及版本、
    浏览器 及版本等信息。在做爬虫时加上此信息,
    可以伪装为浏览器;如果不加,很可能会被识别出为爬虫 # 重点 
    ***********************************************
    5.x-requested-with :XMLHttpRequest      #代表ajax请求 
    6.Accept-Language:指定客户端可接受的语言类型 
    7.Accept-Encoding:指定客户端可接受的内容编码 
    8.Content-Type:也叫互联网媒体类型(Internet Media Type)
    或者MIME类型,在HTTP协议消息头 中,它用来表示具体请求中的媒体类型信息。
    例如,text/html代表HTML格式,image/gif代表GIF图片, 
    application/json代表JSON类型

4、反爬与反反爬

1.反爬机制: 
    1).UA检测   2).IP封禁   3).robots协议        4).账号封禁   
     5).验证码  6).动态数据加载   7).图片懒加载  8).隐藏参数 
      9).js加密-->js逆向
      
2.反反爬策略:  
    1).UA伪装   2).IP代理池  3).settings设置     4).cookie池  
     5).第三发打码平台  6).1.selenium  2.ajax  3.js逆向

5、常见的状态码

# 响应状态码: 用于判断请求后的相应状态, 如200代表请求成功, 
404代表页面页面找不到, 500代表服务 器错误 # 常见的状态码: 
	200系列:
        200 成功 服务器已成功处理了请求 # 重点1 
        
    300系列: 
        301 永久移动 请求的网页已永久移动到新位置,即永久重定向 # 重点 
        302 临时移动 请求的网页暂时跳转到其他页面,即暂时重定向 # 重点 
        
    400系列: 
        400 错误请求 服务器无法解析该请求 # 重点 
        401 未授权 请求没有进行身份验证或验证未通过 
        403 禁止访问 服务器拒绝此请求 # 重点 
        404 未找到 服务器找不到请求的网页 
        
    500系列:
        500 服务器内部错误 服务器遇到错误,无法完成请求 # 重点 
        501 未实现 服务器不具备完成请求的功能 
        502 错误网关 服务器作为网关或代理,从上游服务器收到无效响应 
        504 网关超时 服务器作为网关或代理,但是没有及时从上游服务器收到请求 
        505 HTTP版本不支持 服务器不支持请求中所用的HTTP协议版本
        
**(注意: 状态码不能完全代表响应状态, 部分网站的状态码是自定义的, 
一切以响应的数据为准)**

6、响应头

# 响应头: (了解即可)
响应头包含了服务器对请求的应答信息 
	Date:标识响应产生的时间。 
    Content-Encoding:指定响应内容的编码。 
    Server:包含服务器的信息,比如名称、版本号等。 
    Content-Type:文档类型,指定返回的数据类型是什么,
    如text/html代表返回HTML文档
    application/x-javascript则代表返回JavaScript文件,
    image/jpeg则代表返回图片。 
    Set-Cookie:设置Cookies。响应头中的Set-Cookie告诉浏览器
    需要将此内容放在Cookies中,下次请 求携带Cookies请求。 
    Expires:指定响应的过期时间,可以使代理服务器或浏览器
    将加载的内容更新到缓存中。如果再次访问时, 就可以直接从缓存中加载,
    降低服务器负载,缩短加载时间。

7、响应体

# 响应体: --------------重要
最重要的当属响应体的内容了。响应的正文数据都在响应体中,
比如请求网页时,它的响应体就是网页的HTML 代码;请求一张图片时,
它的响应体就是图片的二进制数据。我们做爬虫请求网页后,
要解析的内容就是响应体.

8、网页基础

# 网页的组成: 
网页可以分为三部分, HTML, CSS, JavaScript 

1.HTML: 其全称叫作Hyper Text Markup Language,即超文本标记语言。
 定义了网页的骨架 
2.CSS: 全称叫作Cascading Style Sheets,即层叠样式表。 定义了网页的样式 
3.JavaScript: 简称JS,是一种脚本语言 定义了网页与用户的交互行为,
 如下载进度条, 提示框, 轮播图

9、爬虫工作流

1.确定url, 向服务器发送请求并获得响应: requests, urllib, aiohttp 
2.在响应中提取目标数据, 即数据解析: xpath, bs4, 正则, PyQuery 
3.数据持久化: 文件, 关系型数据库, 非关系型数据库

10、抓包技能操作认识

***抓包在页面右键检查 或者 F12键
1.箭头---快速定位页面的某个元素(如果在页面定位元素没显示,
	用快捷键(ctrl+shift+c))
2.小方块---变成手机版的页面
3.Elements---包含页面的所有元素(所有响应数据的集合,也可以快速定位)
4.Network---(重要)网络抓包[Preserve log:保留请求日志,
	Disable cache:不缓存,缓存提高访问速度]
5.抓包---Headers:包含所有的头部信息,Preview:预览内容,
	Response:响应内容(搜索:Ctrl+f查询)

11、requests 模块请求

import requests
#1.确定url,发起请求,获取响应
url = '链接地址'
res = requests.get(url=url)
print(type(res.text))----------输出获取的是一个字符串
with open('zhihu.html','w',encoding='utf-8') as f:
    #res是一个响应对象
    #f.write(字符串)
    f.write(res.text)
   

12 、requests 模块基本使用

# requests库的安装 
pip install requests
1.get请求: 
    不携带参数的get请求: 搜狗首页 
    不携带参数的get请求 + headers: 
    爬取知乎的发现页 携带参数的get请求 + headers: 知乎的发现栏中搜索Python 
    # parameters 的缩写 params--{}字典的形式--拼接再url?后面
    	(也可以封装函数,传参)
    res = requests.get(url=url, headers=headers, params=params,
    		proxies=proxies) 
    
2.post请求: 构建参数的post请求 
    # data 数据(在网页Form Data里)响应数据是json数据类型--字典{}
    res = requests.post(url=url, headers=headers, 
    					data=data,proxies=proxies)
    
3. json形式与流形式的响应数据示例

	json.dumps	将 Python 对象编码成 JSON 字符串
	json.loads	将已编码的 JSON 字符串解码为 Python 对象
    
	# json形式响应数据示例: bilibili的Python视频教程, 目录列表 
    import requests 
    headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0;
     Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
      Chrome/75.0.3770.142 Safari/537.36' }
    url = 'https://api.bilibili.com/x/web-interface/view?
    aid=14184325&cid=23153678' 	
    res = requests.get(url=url, headers=headers) 
    print(res) 
    print(res.status_code) 
    print(res.headers) 
    print(res.json())
4.响应数据的获取与属性 
	(1).响应数据的获取: 
        res.text: 文本数据 
        res.json(): json数据 ------->dict
        res.content:, 图片, 视频, 压缩包, 软件包 
    (2).响应的其他属性:
        res.status_code: 获取响应状态码 
        res.headers: 响应头
        res.cookie: cookie信息
        res.history: 历史

13、代理 IP

#goubanjia.com   IP代理商
#proxy   变成了  proxies的参数{}
正向代理:对于浏览器知道服务器的真实地址,例如VPN
反向代理:浏览器不知道服务器的真实地址,例如nginx

代理IP的分类
根据代理ip的匿名程度,代理IP可以分为下面四类:

透明代理(Transparent Proxy):透明代理虽然可以直接“隐藏”你的IP地址,
							但是还是可以查到你是谁。
匿名代理(Anonymous Proxy):使用匿名代理,别人只能知道你用了代理,
							无法知道你是谁。
高匿代理(Elite proxy或High Anonymity Proxy):高匿代理让别人根本无法发现你
							是在用代理,所以是最好的选择。

从请求使用的协议可以分为:

http代理
https代理
socket代理等
不同分类的代理,在使用的时候需要根据抓取网站的协议来选择
import random 
ip-list = ['']
proxies = {
    'https':'http:// %s' % random.choice(ip-list)
}

三、requests 高级

1、文件上传功能

#用的少---应用场景(可以当时上传文件)
import requests 
# 定义上传文件数据, 键为file, 值为文件句柄
files = {
'file': open('favicon.ico', 'rb')
}
#指定网址,指定字段
r = requests.post('http://httpbin.org/post', files=files)
print(res.text)
会话***代理设置

2、cookie处理*

# cookie处理方式
	1.headers添加cookie键值对 ---->Session
    2.RequestsCookieJar对象
#2. RequestsCookieJar对象处理cookie: 用cookie维持百度登陆
#爬知乎
import requests
from requests.cookies import RequestsCookieJar
cookies = 'BAIDUID=79A570F8D90B2C45E42D40A3666ADC46:FG=1; 
BIDUPSID=79A570F8D90B2C45E42D40A3666ADC46;
 PSTM=1551074009; BD_UPN=12314753; sugstore=0; 
 BDORZ=FFFB88E999055A3F8A630C64834BD6D0; 
 yjs_js_security_passport=10c9ca61409abe70ac5c03db79
 6f78648e697d8f_1563711806_js; COOKIE_SESSION=2860_2_2_7_3_5_0_0_2_
 4_106_0_3778_177561_116_109_1563714759_15
 63714752_1563714643%7C9%23177557_14_156
 3714643 %7C7; delPer=0; BD_HOME=0; H_PS_PSSID=1452_21117_29522_29521_2
 8519_29099_28831_29221; BDUSS=lSVnBVVkRVNFpNZ2ZJZ2ZpNFpjblFFSX5Ea
 W9DNzBpcnNkaDZIQVdRd2Z1bHhkRVFBQUFBJCQ
 AAAAAAAAAAAEAAABwfMtW09rQodPjMDgyMGZyZWU
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8tNV0fLTVdYX'

headers = {
    'User-Agetn': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'
}
#实例化对象
jar = RequestsCookieJar()
#分割
cookie_list = cookies.split(';')
for cookie in cookie_list:
    #再以等号分割
    key, value = cookie.split('=', 1)
    
    jar.set(key, value)
    
res = requests.get('http://www.baidu.com', cookies = jar,
 headers=headers)
print(res.text)  # 响应数据中包含用户名信息, 说明cookie生效

3、会话维持与模拟登陆

# HTTP无状态:
	使用requests模块中的get()和post()方法请求网页时, 每一次请求都是独立的,
	 没有连续请求之间的状态保持. 假象, 如果你登陆了淘宝后向查看订单, 
	 那么如果没有状态的维持就无法实现.
    
# 会话的维持: Session对象
from requests import Session
s = Session()
res = s.get('https://www.baidu.com')
	#PyExecJS
    #js2py    加密
# 人人网登陆案例:
from requests import Session 
session = Session() 
url = 'http://www.renren.com/ajaxLogin/login?
1=1&uniqueTimestamp=2019761744568' 
headers = { "USer-Agent":'Mozilla/5.0 (Windows NT 10.0; Win64; x64) 
AppleWebKit/537.36 
(KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36' }
data = { 'email': '17679962330', 'autoLogin': 'true', 'icode': '',
 'origURL': 'http://www.renren.com/home', 'domain': 'renren.com',
  'key_id': '1', 'captcha_type': 'web_login', 
  'password': '6ea935849c9dbfc4ac484718ac8652a14f4b2f
  60036de7a279e84be08bc54136', 
  'rkey': '1c7df63368df7ce73c234de26178ec11',
   'f': 'http%3A%2F%2Fwww.renren.com%2
  F972036549%2Fnewsfeed%2Fphoto', }
res = session.post(url=url, data=data, headers=headers) 
ret = session.get(url='http://www.renren.com/972036549/profile', 
headers=headers) ret.encoding = 'utf-8' 
with open('renren.html', 'w', encoding='utf-8') as f: 
    f.write(ret.text)

4、SSL证书验证

# 1.SSL证书验证
requests提供了证书验证的功能. 当发起HTTP请求时, 模块会检查SSL证书. 
但检查的行为可以用verify参数来控制.
	verify = False  # 不检查SSL证书
	verify = True  # 检查SSL证书
    
# 2.异常
如果使用requests模块的SSL验证, 验证不通过会抛出异常, 
此时可以将verify参数设置为False

# 3.www.12306.cn的证书验证
# 会抛出异常
import requests
response = requests.get('https://www.12306.cn')
print(response.status_code)

# 不抛异常, 但会出现警告
import requests
response = requests.get('https://www.12306.cn', verify=False)
print(response.status_code)

# 异常: SSLError 
requests.exceptions.SSLError        #证书错误

# 禁止警告
import requests
from requests.packages import urllib3
urllib3.disable_warnings()
response = requests.get(url='https://www.12306.cn', verify=False)
print(response.status_code)

5、代理设置

# 代理: 代理即代理ip 
代理ip是指在请求的过程中使用非本机ip进行请求, 
避免大数据量频繁请求的过程中出现ip封禁, 限制数据 的爬取. 

# 代理ip分类: 
	1.透明代理ip: 请求时, 服务器知道请求的真实ip, 知道请求使用了代理 
    2.匿名代理ip: 请求时, 服务器知道请求使用了代理, 但不知道请求的真实ip 
    3.高匿代理ip: 请求时, 服务器不知道请求使用了代理, 也不知道请求的真实ip 
    #基于隧道:云端维护了一个庞大的IP代理池,每次请求换一个IP
    #提供接口:返回一部分数量的IP,配合IP代理池使用
        
# requests模块使用代理ip 
import requests 
url = 'http://www.httpbin.org'
proxies = { 'http': 'http://61.183.176.122:57210' }
res = requests.get(url=url, proxies=proxies) 
print(res.text)

6、超时设置

# 超时设置: 
	由于网络状况的不同, 服务器配置差异以及服务器处理并发的能力不同,
	 有时会出现服务器的响应时间 过长, 甚至无法获取响应而抛出异常. 
	 requests模块发送请求可以设置超时时间, 在超时时间内未得到响 应,
	  便会抛出异常. 
	一方面, 减少了请求的阻塞时间, 一方面, 可以进行异常处理, 执行相应的操作. 
	
import requests 
url = 'https://www.baidu.com' 
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) 
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36' }

res = requests.get(url=url, headers=headers, timeout=0.001) 
# 在0.001秒为得到响 应, 抛出requests.exceptions.ConnectTimeout异常 
print(res.text)

7、构建Request对象、

# 1.Prepared Request 
利用 Prepared Request 数据结构构建Request对象. 其构建及使用步骤如下: 
from requests import Request, Session 
# 构建Request对象 
url = '...' 
data = {... }
params = {... }
headers = {... }
session = Session() 
# 构建post请求: 
req_post = Request(method='POST', url=url, headers=headers, data=data) 
req_obj_post = session.prepare_request(req_post)

# 构建get请求: 
req_get = Request(method='GET', url=url, headers=headers, params=params) 
req_obj_get = session.prepare_request(req_get) 
# 利用构建的请求对象, 向服务器发送请求 
res = session.send(req_obj_post) 
res = session.send(req_obj_get) 
# 应用: 通过此方法, 我们可以构建一个独立的request对象, 当需要请求的url很多时, 
我们可以为每一个url构建 一个request对象, 将所有request对象置于队列中, 
便于调度.

# 构建request对象, 请求糗事百科获取页面 
from requests import Request, Session 
url = 'https://www.qiushibaike.com/' 
headers = { "User-Agent":'Mozilla/5.0 (Windows NT 10.0; Win64; x64) 
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36' }

session = Session() 
req_get = Request(url=url, headers=headers, method='GET') 
req_get_obj = session.prepare_request(req_get) 
res = session.send(req_get_obj) 
res.encoding = 'utf-8' 
with open('qb_reqobj.html', 'w', encoding='utf-8') as f: 
    f.write(res.text)

8、urllib简单介绍

# urllib简介: 
1.urllib模块是Python的一个请求模块 
2.Python2中是urllib和urllib2相结合实现请求的发送. Python3中统一为urllib库 
3.urllib是Python内置的请求库, 其包含4个模块: 
	(1).request模块: 模拟发送请求 
	(2).error模块: 异常处理模块 
	(3).parse模块: 工具模块, 提供关于URL的处理方法, 如拆分, 解析, 合并等 
	(4).robotparser模块: 识别robots协议

# 部分方法使用介绍:
# urlopen方法实现get请求: 
from urllib import request 
url = 'https://www.python.org' 
res = request.urlopen(url) 
print(res.read()) 
with open('python.html', 'w') as f: 
    f.write(res.read().decode('utf-8'))
    
# post请求: 
import urllib.request 
import urllib.
parse url='https://fanyi.baidu.com/sug' 
postdata=urllib.parse.urlencode({'kw':'boy'}).encode('utf-8') 
res = urllib.request.urlopen(url, data=postdata) 
print(res.read())

# urlretrive实现图片下载: 
from urllib.request import urlretrieve 
urlretrieve('https://www.dxsabc.com/api/xiaohua/upload/min_img/
20190213/20190213 XTUcIZ99B9.jpg', 'bing.jpg')

9、正则介绍

# 1.元字符匹配 
. 匹配任意字符,除了换行符(重要) 
[] 用来表示一组字符,单独列出:[abc] 匹配 'a','b'或'c' 
[^...] 匹配除了字符组中字符的所有字符 
\d 匹配任意数字,等价于 [0-9]. 
\D 匹配任意非数字 
\w 匹配字母数字及下划线 
\W 匹配非字母数字及下划线

\s 匹配任意空白字符,等价于 
[\t\n\r\f]. \S 匹配任意非空字符

# 2.字符组: 要求在一个位置匹配的字符可能出现很多种情况, 各种情况组成一个组 
[0123456789]: 匹配0到9任意字符 
[0-9]: 同上 [a-z]: 匹配a到z的任意小写字母 
[A-Z]: 匹配A到Z的任意大写字母 
[0-9a-fA-F]: 以上三种的组合, 匹配0-9任意数组或a到f之间任意字母, 不区分大小写 
自定义字符组:[a3h5] ---> 代表匹配a, 3, h, 5等字符
    
# 3.量词: 
* 重复零次或更多次 
+ 重复一次或更多次 
? 非贪婪匹配 
{n} 重复n次 
{n,} 重复n次或更多次 
{n,m} 重复n到m次 
{,m} 重至多m次

# 4.边界修饰符 
^ 匹配开始 
$ 匹配结尾

# 5.分组(重点, 重点, 重点) 
在正则表达式中添加(), 就形成了一个分组, 在re模块中优先匹配显示分组内容 
import re 
s = "<a href='www.baidu.com'>正则匹配实验</a>" 
res = re.findall("href='(.*)'>", s) 
print(res)

# 6.贪婪匹配与非贪婪匹配 
贪婪匹配是指: 在使用量词: * , + 等时, 尽可能多的匹配内容 
非贪婪匹配是指: 使用?对正则表达式进行修饰, 使量词的匹配尽可能少, 如+代表匹配1次或多次, 在?的修 饰下, 只匹配1次.
    
# 7.匹配模式 
re.S 单行模式(重点) 
re.M 多行模式 
re.I 忽略大小写 
# 示例: 
import re 
s = 'hello2world\nhello3world\nhello4world' 
#re.M 多行模式 
result0 = re.findall(r'\d.*d', s) 
print(result0) 
result1 = re.findall(r'\d.*d', s, re.M) 
print(result1) 
#re.S 单行模式(可以看成将所有的字符串放在一行内匹配包括换行符\n) 
result2 = re.findall(r'\d.*d', s, re.S)
print(result2) 
result3 = re.findall(r'\d.*?d', s, re.S) 
print(result3)

# 8.re模块 
1.re.findall('正则表达式', '待匹配字符串'): 返回所有满足匹配条件的结果, 以列表形式返回 2.re.search('正则表达式', '带匹配字符串'): 匹配到第一个就返回一个对象, 该对象使用group()进 行取值, 如果未匹配到则返回None 
3.re.match('正则表达式', '待匹配字符串'): 只从字符串开始进行匹配, 如果匹配成功返回一个对象, 同样使用group()进行取值, 匹配不成功返回None 
4.re.compile('正则表达式'): 将正则表达式编译为对象, 在需要按该正则表达式匹配是可以在直接使用 该对象调用以上方法即可. 
    
Python语言: 解释型语言 
    先解释在执行: 源代码 --> 简单的翻译 --> 字节码 --> 二进制语言 --> 识别的语言 
    .pyc文件: 执行过的文件, 生成一个.pyc文件, 再执行时对比. 
C: 编译型语言 源代码 ---> 编译 ---> 二进制文件 --> 识别的语言 
    
# 示例: 
import re 
s = "pythonpython你好吊" 
# findall方法演示 
res_findall = re.findall(r'p', s) 
print('findall匹配结果:', res_findall)

# search方法演示, 不确定是否能匹配出结果, 不可直接使用group进行取值, 
需要判断或进行异常处理 res_search = re.search(r"你", s) 
if res_search: 
    print('search匹配结果', res_search.group()) 
else:
    print('None') 
    
# match方法演示: 
res_match_1 = re.match(r'py', s) 
res_match_2 = re.match(r'thon', s) 
print('res_match_1结果:', res_match_1) 
print('res_match_2结果:', res_match_2) 
# compile方法演示: 
re_obj = re.compile(r'python') 
res = re.findall(re_obj,s) print(res)

10、校花网图片爬取与多页爬取

import re
import requests
for j in range(2):
    # url = 'http://www.xiaohuar.com/list-1-'+str(j)+'.html'
    #获取当前网页地址
    url = 'http://www.xiaohuar.com/list-1-%s.html'% j
    # 头部伪装
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) 
        AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 
        Safari/537.36'
    }
    #获取响应,以文本文档的形式输出
    res = requests.get(url=url)
    # print(res.text)
    #用findall的正则匹配(src="(\d.*?\.jpg)/></a>"),符合条件的都存入列表
    ret = re.findall(r'src="(\d.*?\.jpg)" /></a>',res.text)
    # print(ret)
    # 循环遍历
    for i in ret:
        #每张图片都配置个地址
        url = 'http://www.xiaohuar.com'+i
        #获取响应以二进制流写入
        ret1 = requests.get(url=url,headers=headers).content
        name = i.split('/')[-1]
        #以文件打开方式存入img文件夹中
        with open('../img/'+name,'wb') as f:
            f.write(ret1)
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值