[TOC]
requests 模块
requests模块
:发送 http 请求,获取响应数据;安装pip/pip3 install requests
。
requests 请求方式
respose = requests.get(url,data)
:data 为 post 数据,为一个字典response = requests.post(url,data)
response = requests.put()
response = requests.delete()
response = requests.head()
response = requests.options()
requests 模拟浏览器
headers参数
:接收字典形式的请求头即 key:valueparams参数
:一个参数字典,里面可以带 cookie;比如 get 请求的?id = 1 则 {“id”:1}cookie参数
:字典形式;每一个 cookie 都要写成 key:value 的形式timeout参数
:timeout = 3表示发送请求后,3秒钟内返回响应,否则就抛出异常proxies参数
:proxy 代理参数通过指定代理ip,让代理ip对应的正向代理服务器转发我们发送的请求,比如:proxies = {
“http”: “http://1.1.1.1:9527“,
“https”: “https://1.1.1.2:9527“,
}注意:如果proxies字典中包含有多个键值对,发送请求时将按照url地址的协议来选择使用相应的代理ip
files参数
:文件上传,字典形式;eg:files = {'file':open('favicon.ico','rb')}
verify参数
:SSL证书认证,当发送HTTPS请求的时候,会检查SSL证书,verify
参数可以控制是否检查SSL证书。auth参数
:身份认证
requests 响应对象
response.text
- 类型:str
- 解码类型: requests模块自动根据 HTTP 头部对响应的编码作出有根据的推测,推测的文本编码
response.content
==> 可以解决中文乱码的情况- 类型:bytes
- 解码类型: 没有指定,默认utf-8
response.url
:响应的url;有时候响应的url和请求的url并不一致response.status_code
:响应状态码response.request.headers
:响应对应的请求头response.headers
:响应头response.request._cookies
: 响应对应请求的cookie;返回cookieJar类型response.cookies
:响应的cookie(经过了set-cookie动作;返回cookieJar类型)response.json()
:自动将json字符串类型的响应内容转换为python对象(dict or list)response.raise_for_status()
:主动抛出状态码异常
requests.utils.dict_from_cookiejar()
函数可以把cookieJar类型转换为字典类型
import requests
# 目标url
url = 'https://www.baidu.com'
# 向目标url发送get请求
response = requests.get(url)
# 打印响应内容
#print(response.text)
#print(response.content.decode())
print("------------------------------------------------")
print(response.url) # 打印响应的url
print("------------------------------------------------")
print(response.status_code) # 打印响应的状态码
print("------------------------------------------------")
print(response.request.headers) # 打印响应对象的请求头
print("------------------------------------------------")
print(response.headers) # 打印响应头
print("------------------------------------------------")
print(response.request._cookies) # 打印请求携带的cookies
print("------------------------------------------------")
print(response.cookies) # 打印响应中携带的cookies
requests.session 会话保持
requests 模块中的 session 类能够自动处理发送请求获取响应过程中产生的 cookie ,进而达到状态保持的目的。
- requests.session的作用
- 自动处理cookie,即 下一次请求会带上前一次的 cookie
- requests.session的应用场景
- 自动处理连续的多次请求过程中产生的 cookie
session对象发送get或post请求的参数,与requests模块发送请求的参数完全一致
session = requests.session() # 实例化session对象
response = session.get(url, headers, ...)
response = session.post(url, data, ...)
Python 正则
正则表达式具有通用型,不仅 python 里面可以用,其他的语言也一样适用。
python 中re
模块提供了正则表达式的功能,常用的有四个方法(match、search、findall)都可以用于匹配字符串
match
re.match()
必须从字符串开头匹配!match 方法尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match 就返回none。
函数原型:
res = re.match(pattern, string)
# pattern 匹配的正则表达式
# string 要匹配的字符串
# 返回一个匹配对象
res.group() ==> 获取匹配内容
res.span() ==> 获取匹配内容的位置,左闭右开
eg:
import re
s = "123abc123"
pattern = '123'
res = re.match(pattern, s)
print(res)
print(res.span())
print(res.group())
"""
输出:
<re.Match object; span=(0, 3), match='123'>
(0, 3)
123
"""
总结:
re.match()
方法返回一个匹配的对象,而不是匹配的内容。如果需要返回内容则需要调用group()
。通过调用span()
可以获得匹配结果的位置。而如果从起始位置开始没有匹配成功,即便其他部分包含需要匹配的内容,re.match()也会返回None。
search
和 match 用法基本相同,但是 search 是从字符串中进行搜索,而不是起始位置开始
findall
findall 是寻找所有能匹配到的字符,并以列表的方式返回
re.S
属性:
在字符串a中,包含换行符\n,在这种情况下
- 如果不使用re.S参数,则只在每一行内进行匹配,如果一行没有,就换下一行重新开始。
- 而使用re.S参数以后,正则表达式会将这个字符串作为一个整体,在整体中进行匹配。
eg:
import re
a = """aaatestaa
aaaa123"""
print(re.findall('test.*123',a))
print(re.findall('test.*123',a,re.S))
"""
输出:
[]
['testaa \naaaa123']
"""
sub、split
sub()
:查找字符串中所有相匹配的数据进行替换
re.sub(pattern, replace, string)
split()
:对字符串进行分割,并返回一个列表
re.split(pattern, string)
网页解析
bs4
bs4 简介
即BeautifulSoup,是python种的一个库,最主要的内容就是从网页中抓取数据。
BeautifulSoup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据。
BeautifulSoup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。你不需要考虑编码方式,除非文档没有指定一个编码方式;这时,BeautifulSoup就不能自动识别编码方式了。然后,你仅仅需要说明一下原始编码方式就可以了。
bs4 基本使用
节点查找
节点信息
from bs4 import BeautifulSoup
html_doc = """<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
#创建一个BeautifulSoup对象
bs = BeautifulSoup(html_doc, "html.parser")
print('---------------------------------------------')
#格式化输出全部内容
print(bs.prettify())
print('---------------------------------------------')
#取出title标签
print(bs.title, type(bs.title), dir(bs.title), sep='\n-----------------\n')
print('---------------------------------------------')
#取出第一个a标签
print(bs.a)
print('---------------------------------------------')
#取出a标签的所有属性,字典形式
print(bs.a.attrs)
print('---------------------------------------------')
#取出a标签的具体属性值
print(bs.a.attrs['href'])
print('---------------------------------------------')
#判断a标签是否有某属性
print(bs.a.has_attr('xxx'))
print('---------------------------------------------')
#bs.p.children取出第一个p标签的所有子节点,是一个迭代器
print(bs.p.children)
print(list(bs.p.children))
print(list(bs.p.children)[0])
print(list(bs.p.children)[0].text)
print('---------------------------------------------')
#找到所有标签:bs.find_all('tag'),返回一个列表
print(bs.find_all('a'))
for a in bs.find_all('a'):
print(a.attrs['href'])
print('---------------------------------------------')
#找到包含某个属性的标签(如果有多个只返回第一个)
print(bs.find(class_='sister'))
print('---------------------------------------------')
#去掉标签,只输出内容
print(bs.get_text())
print('---------------------------------------------')
print('---------------------------------------------')
print('---------------------------------------------')
print('---------------------------------------------')
lxml
xpath 基础
表达式 | 功能描述 |
---|---|
nodename | 选中所有子节点。 |
/ | 从根节点选取、或者是元素和元素间的过渡。 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
. | 选取当前节点。 |
.. | 选取当前节点的父节点。 |
@ | 选取属性。 |
text() | 选取文本。 |
from lxml import etree
html_doc = """<bookstore>
<book category="COOKING">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="CHILDREN">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="WEB">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
"""
#创建选择器对象
selector = etree.HTML(html_doc)
#取出页面所有链接
print(selector.xpath('book'))
print('---------------------------------------------')
print(selector.xpath('//book'))
print('---------------------------------------------')
#选取所有书作者的名字
print(selector.xpath('//bookstore/book/author/text()'))
print('---------------------------------------------')
#选取所有书的语言
print(selector.xpath('//bookstore/book/title/@lang'))
print('---------------------------------------------')
#选取第1本书的标题
print(selector.xpath('//book[1]/title/text()'))
print('---------------------------------------------')
#选取最后1本书的标题
print(selector.xpath('//book[last()]/title/text()'))
print('---------------------------------------------')
#选取倒数第2本书的标题
print(selector.xpath('//book[last()-1]/title/text()'))
print('---------------------------------------------')
#选取前两本书的标题
print(selector.xpath('//book[position()<3]/title/text()'))
print('---------------------------------------------')
#选取分类为WEB的书
print(selector.xpath('//book[@category="WEB"]/title/text()'))
print('---------------------------------------------')
#选取价格≥30的书
print(selector.xpath('//book[price>=30]/price/text()'))
print('---------------------------------------------')
#属性有多个值可以使用contains(@name, value)
print('---------------------------------------------')
print('---------------------------------------------')
print('---------------------------------------------')
print('---------------------------------------------')
"""
xpath:在XML文档中查找信息的语言
概念:
节点、属性、文本、命名空间、文档(根)节点
节点关系:
父 parent、子 children、同胞 sibling、先辈 ancestor、后代 descendant
nodename 选取所有子节点
// 从任意子节点中选取
/ 从根节点选取
@ 选取属性
"""
实战
下厨房主页图片爬取
import os
from bs4 import BeautifulSoup
import requests
url = "https://www.xiachufang.com/"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.0.12022 SLBChan/103"
}
session = requests.session()
res = session.get(url=url, headers=headers)
bs = BeautifulSoup(res.text, 'html.parser')
img_url = []
all_img = bs.find_all('img')
for i in all_img:
if i.has_attr('data-src'):
img_url.append(i.attrs['data-src'].split('?')[0])
else:
img_url.append(i.attrs['src'].split('?')[0])
for urll in img_url:
filename = os.path.join(os.curdir, 'spider\img\\' + urll.split('/')[-1])
res = session.get(url=urll, headers=headers)
with open(filename, 'wb') as f:
f.write(res.content)