定向网络数据爬取和网页解析的基本能力
安装方法
**>>> import requests
>>> r= requests.get("http://www.baidu.com")
>>> r.status_code
200
>>> r.encoding='utf-8'
>>> r.text**
requests库的7个主要方法
requests.request() | 构造一个请求,支持以下各方法的基础方法 |
---|---|
requests.get() | 获取HTML网页的主要方法,主要对应HTTP的GET |
requests.head() | 获取HTML网页头信息的主要方法,主要对应HTTP的HEAD |
requests.post() | 向HTML网页提交POST请求的方法,主要对应HTTP的POST |
requests.put() | 向HTML网页PUT请求的方法,主要对应HTTP的PUT |
requests.patch() | 向HTML网页计较局部修改请求的方法,主要对应HTTP的PATCH |
requests.delete() | TML网页提交删除请求方法,主要对应HTTP的DELETE |
r=requests.get(url) 构建一个向服务器请求资源的Request对象。Request对象是大写
requests.get()返回一个包含服务器资源的Response对象,用变量r表示
**requests.get(url,params=None,kwargs)
Response对象的属性
r.status_code | HTTP请求的返回状态 |
---|---|
r.text | HTTP响应内容的字符串形式,即,url对应的页面内容 |
r.encoding | 从HTTP header中猜测的响应内容编码方式,从HTTP的header的charset字段获得,如果由这个编码,说明我们访问的服务器对他资源的编码有要求。但并不是都是有要求,如果header中没有charser,则认为编码为ISO-8859-1 |
r.apparent_encoding | 从内容中分析出的响应内容编码方式(备选编码方式)更准确 |
r.content | HTTP响应内容的二进制形式,如果从一个url图片,图片是以二进制存储的,就可以用r.content还原他 |
流程
requests.get(url)并不是总是有效的,网络连接有风险,异常处理很重要
Requests库的异常
异常 | 说明 |
---|---|
requests.ConnectionError | 网络连接错误异常,如DNS查询失败,拒绝连接等 |
requests.HTTPError | HTTP错误异常 |
requests.URLRequired | URL缺失异常 |
requests.TooManyRedirects | 超过最大重定向次数,产生重定向异常(经常是对一些复杂的链接访问时的错误) |
requests.ConnectTimeout | 连接远程服务器超时异常(仅仅是连接) |
requests.Timeout | 请求URL超时,产生超时异常(发起到获得url连接的整个过程) |
理解requests库的异常
异常 | 说明 |
---|---|
r.raise_for_ststus() | 如果不是200,产生异常resquest.HTTPError |
通用代码框架中使用try except语句处理异常,可以有效地处理访问或爬取网页过程中可能出现的错误和网络不稳定现象,使用户访问或爬取网页变得更加有效,更稳定,更可靠
import requests
def getHTMLText(url):
try:
r= requests.get(url)
r.raise_for_status()
r.encoding=r.apparent_encoding
return r.text
except:
print("产生异常")
if __name__=="__main__":
url="http://www.baidu.com"
print(getHTMLText(url))
#
if name == “main”: 是 Python 中的一个常见用法,用于判断当前模块是否作为主程序运行。它的作用如下:
HTTP,Hypertext Transfer Protocol 超文本传输协议
HTTP是一个基于“请求与响应”模式的,无状态的应用层协议
HTTP协议采用URL作为定位网络资源的标识
URL是通过HTTP协议存取资源的Internet路径,一个URL对应一个数据资源
方法 | 说明 |
---|---|
GET | 请求获取URL位置的资源 |
HEAD | 请求获取URL位置的资源的响应报告,即获取该资源的头部信息 |
POST | 请求向URL位置的资源后附加新的数据 |
PUT | 请求向URL位置存储一个资源,覆盖原URL位置的资源 |
PATCH | 请求局部更新URL位置的资源,即改变该处资源的部分内容 |
DELETE | 请求删除URL位置存储的资源 |
假设URL位置由一组数据UserInfo,包括UserID,UserName等20个字段
需求:用户修改了UserName,其他不变
PATCH好处:节省网络带宽
request方法是所有方法的基础方法
requests.request(method,url.**kwarges)
method:请求方式
method==OPTIONS时:向服务器获取一些服务器和客户端打交道的参数,并不与获取资源直接相关,用的较少。
**kwargs:控制访问的参数,均为可选项,因为他是用于收集任意数量的关键字实参
params:字典或字节序列,作为参数增加到URL中
kv={'key1':'value1','key2':'value2'}
r=requests.request('GET','Http://python123/.in/ws',params=kv)
print(r.URL)
Http://python123/.in/ws?key1=value1,key2=value2
data:字典,字节序列或文件对象,作为Request的内容
kv={'key1':'value1','key2':'value2'}
r=requests.request('POST','Http://python123/.in/ws',data=kv)
body='主题内容'
r=requests.request('POST','Http://python123/.in/ws',data=body)
JSON:JSON格式化的数据,还作为Request内容
kv={'key1':'value1','key2':'value2'}
r=requests.request('POST','Http://python123/.in/ws',json=kv)
headers 字典HTTP定制头 (模拟浏览器可以)
hd={'user-agent':'Chrome/10'}
r=requests.request('POST','http://python123.io/ws',headers=hd)
cookies:字典或CookieJar,Request中的cookie
auth:元组,支持HTTP认证功能
files:字典类型,传输文件
fs={'file':open('data.xls','rb')}
r=requests.request('POST','http://python123.io/ws',files=fs)
- fs={'file':open('data.xls','rb')} :
- 打开名为 data.xls 的文件,以二进制只读模式 ( 'rb' ) 读取。
- 创建一个字典 fs ,其中键为 'file' ,值为打开的文件对象。这个键名通常对应服务器端接收文件的字段名。
- requests.request('POST','http://python123.io/ws',files=fs) :
- 使用 requests 库发送一个 HTTP POST 请求。
- 'POST' 指定请求方法为 POST。
- 'http://python123.io/ws' 是目标 URL,即文件要上传到的服务器地址。
- files=fs 指定要上传的文件, fs 是之前创建的文件字典。
- 整体功能 :
- 将本地的 data.xls 文件通过 POST 请求上传到 http://python123.io/ws 这个地址。
- 服务器会以 'file' 作为字段名接收这个文件。
timeout:设定超时时间,秒为单位
r=requests.request('GET','http://python123.io/ws',timeout=10)
proxies:字典类型,设定访问代理服务器,可以增加登录认证
pxs={'http':'http://user:[email protected]:1234'
'http':'https://10.10.10.1:4321'}
r=requests.request('GET','http://python123.io/ws',proxies=pxs)
allow_redirects:True/False,默认为True,重定向开关。表示允不允许被URL重定向
Stream:True/False,默认为True,获取内容立即下载开关
verify:True/False,默认为True,认证SSL证书开关
cert:本地SSL证书路径
**requests.get(url,params=None,**kwargs) kwargs:除去params,12个
**requests.head(url,**kwargs) kwargs:13个
requests.post(url,data=None,json=None,**kwargs) **kwargs:11个
requests.put(url,data=None,**kwargs) data:字典,字节序列或文件 **kwargs:12个
requests.patch(url,data=None,**kwargs) **kwargs:12个
requests.delete(url,**kwargs) **kwargs:13个
小规模,数据量小,爬取速度不敏感,Requests库,>90% | 中规模,数据规模较大,爬取速度敏感,Scrspy库 | 大规模,搜索引擎,爬取速度关键,定制开发 |
---|---|---|
玩转爬虫,玩转网页 | 爬取网站 爬取系列网站 | 爬取全网 |
baidu.com/robots.txt
没有Robot协议,就不限制任何爬虫爬取所有内容
#注释 *代表所有 /代表根目录
User-Agent: *
Disallow: /
Robots Exclusion Standard 网络爬虫排除标准
作用:网站告知网络爬虫哪些页面可以爬取,哪些不行
形式:在网站根目录的robots.txt文件
网络爬虫:自动或人工识别robots.txt,再进行内容爬取
建议但非约束性,类人行为可不参考
https://item.jd.com/100123450364.html
import requests
url="https://item.jd.com/100123450364.html"
try:
r=requests.get(url)
r.raise_for_status()
r.encoding=r.apparent_encoding
print(r.text[:1000])
except:
print("爬取失败")
import requests
try:
url=''
kv={'user-Agent':'Mozillo/5.0'}
r=requests.get(url,headers=kv)
r.raise_for_status()
r.encoding=r.apparent_encoding
print(r.text[:10000])
except:
print("爬取错误")
r.status_code
503
r.request.headers
{‘User-Agent’: ‘python-requests/2.28.1’, ‘Accept-Encoding’: ‘gzip, deflate’, ‘Accept’: ‘/’, ‘Connection’: ‘keep-alive’}
kv={‘user-agent’:‘Mozilla/5.0’}
url=‘’
r=requests.get(url,headers=kv)
r.status_code
200
r.request.headers
{‘user-agent’: ‘Mozilla/5.0’, ‘Accept-Encoding’: ‘gzip, deflate’, ‘Accept’: ‘/’, ‘Connection’: ‘keep-alive’}
百度的关键字接口:
http://www.baidu.com/s?wd=keyword
360的关键字接口:
http://www.so.com/s?q=keyword
>>> import requests
>>> kv={'wd':'python'}
>>> r.requests.get('http://www.baidu.com/s',params=kv)
>>> r=requests.get('http://www.baidu.com/s',params=kv)
>>> r.status_code
200
>>> r.request.url
'http://www.baidu.com/s?wd=python'
>>> len(r.text)
1353463
import requests
try:
url="http://www.baidu.com/s"
kv={'wd':'python'}
r=requests.get(url,params=kv)
r.raise_for_status()
print(r.request.url)
length=len(r.text)
print(length)
except:
print("爬取错误")
import requests
import os
try:
url = 'http://img0.dili360.com/ga/M02/33/7C/wKgBzFSbqQyAJVAuAARB8cSWH_w695.tub.jpg'
r = requests.get(url)
r.raise_for_status()
# 指定保存路径和文件名
save_dir = 'D:/software/pycharmpro/program/pythonbooktest/pythonProject0'
filename = os.path.join(save_dir, 'image.jpg')
# 检查文件是否已存在
if os.path.exists(filename):
print("文件已存在")
else:
# 保存文件
with open(filename, 'wb') as f:
f.write(r.content)
print("文件保存成功")
except requests.exceptions.RequestException as e:
print(f"爬取失败: {e}")
except IOError as e:
print(f"文件保存失败: {e}")
with 是 Python 中的一个上下文管理协议(Context Management Protocol),主要用于简化资源管理,确保资源在使用后能够被正确释放。以下是它的详细解释:
with 表达式 as 变量:
代码块
with 语句背后的机制依赖于对象的 enter() 和 **exit**() 方法:
(1) 文件操作
with open('file.txt', 'r') as f:
content = f.read()
# 文件会在代码块结束后自动关闭,无需手动调用 f.close()
(2) 数据库连接
with connect_database() as conn:
conn.execute('SELECT * FROM table')
# 数据库连接会在代码块结束后自动关闭
(3) 线程锁
with threading.Lock():
# 线程安全的代码块
# 锁会在代码块结束后自动释放
不使用 with :
f = open('data.txt', 'w')
try:
f.write('Hello, World!')
finally:
f.close()
使用 with :
with open('data.txt', 'w') as f:
f.write('Hello, World!')
总结: with 是 Python 中用于管理资源(如文件、数据库连接、锁等)的语法糖,能够确保资源在使用后被正确释放,同时简化代码并提高可读性。
os 是 Python 标准库中的一个模块,提供了与操作系统交互的功能。它允许你执行文件操作、目录操作、环境变量管理、进程管理等任务。以下是 os 模块的常用功能:
文件与目录操作
进程管理
文件权限
os.path 是 Python 标准库 os 模块中的一个子模块,专门用于处理文件路径和目录路径。它提供了一系列函数来操作路径字符串,使得路径处理更加方便和跨平台兼容
路径操作
以下是 os.path 中一些常用的函数:
(1) 路径拼接
import os
path = os.path.join('dir1', 'dir2', 'file.txt')
# 输出: 'dir1/dir2/file.txt'(Linux/macOS)或 'dir1\\dir2\\file.txt'(Windows)
(2) 路径拆分
os.path.split(path) :将路径拆分为目录和文件名。
dir, file = os.path.split('/path/to/file.txt')
# dir = '/path/to', file = 'file.txt'
(3) 路径存在检查
os.path.exists(path) :检查路径是否存在。
if os.path.exists('file.txt'):
print('文件存在')
(4) 文件/目录判断
if os.path.isfile('file.txt'):
print('这是一个文件')
if os.path.isdir('dir'):
print('这是一个目录')
(5) 获取文件信息
size = os.path.getsize('file.txt')
mtime = os.path.getmtime('file.txt')
(6) 路径规范化
os.path.normpath(path) :规范化路径(去除冗余的分隔符和 . / … )。
path = os.path.normpath('dir1/./dir2/../file.txt')
# 输出: 'dir1/file.txt'
os.path.abspath(path) :将相对路径转换为绝对路径。
abs_path = os.path.abspath('file.txt')
ip138
import requests
url = "http://ip138.com/ip.asp?ip="
try:
r = requests.get(url+"109.141.155")
r.raise_for_status()
r.encoding = r.apparent_encoding
print(r.text[-500:]) # 修正切片索引
except : # 捕获特定异常
print(f"查询失败")
我搞不出来,可能网站有查询验证,要钱啥的