requests 请求库

发起请求

requests 可以发起 get post put delete head options patch 这些请求。

参数可以携带:

  1. url 请求地址
  2. params 拼接链接的请求参数 get
  3. datas 正文的请求参数 post
  4. headers 请求头内容
  5. verify 是否 https 验证,有 True 和 False 两个值

获取返回内容


通过 request 提供的各种请求方法,返回一个 响应对象 response。

  • response.text 返回 unicode 的 string 对象的相应内容。

  • response.content 返回 二进制 的相应内容。

一定要记得根据编码格式,设置 response.encode = “XXX” 不然返回内容会解析错误。


如果返回的是 json 数据,则调用响应对象的 json() 将其转化为 Python 的 dic 对象。

Session 会话

这里是模拟自动处理响应和请求的 Cookie 处理,在所属于的 Session 会话中,每一次请求都会带上以前保留下来的 Cookie!

1
2
session = requests.session()
session.get(url)

Proxies 代理

Reqeusts 只支持 http 和 https 两个代理,访问的 url 是哪种链接,就匹配哪种代理。目前不支持代理池,需要自己找开源的。

http 访问可以用 https 的代理,反之不可以。

设置字典,然后请求的时候带上去就可以了:

1
2
3
4
5
proxies = {  
'http':"http://61.133.87.228:55443"
'https':"https://124.64.8.50:8000"
}
request.get(url,proxies=proxies)

re 正则

raw string

rstring 表示 raw string 原始字符串,表示这个字符串自动忽略所有的转义符号。常用在正则表达式字符串中,用来忽略 \w \d 这些匹配符号的转义。

1
2
3
regex = r"^[0-5][a-z].*?\\w+\\d+$"  

result = re.compile(regex)

re 常用

注意下面所有的函数,除了输入正则字符串和被匹配字符串以外,还有一个可选参数 flags,多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:

修饰符 描述
re.I 使匹配对大小写不敏感
re.L 做本地化识别(locale-aware)匹配
re.M 多行匹配,影响 ^ 和 $
re.S 使 . 匹配包括 换行 在内的所有字符
re.U 根据 Unicode 字符集解析字符。这个标志影响 \w, \W, \b, \B.
re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。

一般来说,上面最常用的就是 re.S 来让 . 匹配更加强大。

  • re.compile() 预编译正则表达式,返回的对象是编译完成对象,调用下面只需要输入被匹配字符串即可。

  • re.findall() 返回一个匹配的 list

  • re.finditer() 返回一个匹配的迭代器,迭代器内对象为 match,通过的 group() 获取实例,效率高于 list。

  • re.search() 检索第一个符合匹配的,以 match 对象返回。

group() 分组

对于 re.finditer() 的优势中,除了比 list 性能更强以外,还可以对捕获的数据进行分组操作。

正则表达式中 (.*?) 这样的括号用于捕获符合括号里面匹配的内容,我们也可以对捕获的内容进行分类,方法就是添加分类的 group 标签 (?P<name>RegEx) 为符合正则表达式 RegEx 的文本进行分组命名为 name :

然后通过返回的 iter 对象的 group('name') 返回对应分组的数据,或者 groupdict() 以字典的形式返回本次匹配的所有分组数据。

BS4

BeautifulSoup4 一种基于 html 代码分析解析的库。推荐用于定位大量标签类相同的数据获取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from bs4 import BeautifulSoup  

# 首先将响应的 html 页面交给 BeautifulSoup,并告诉它使用 html 解析器:
bs = BeautifulSoup(response,"html.parser") # parser 解析器

# 然后返回的就是一个解析了 HTML 的 DOM 对象,可以通过 find() find_all() 查找更小的 DOM 对象
# 第一个参数是标签名,后面可以跟着 属性名=值 来进行定位。
# 注意所有和 Python 关键字重合的,后面都加上 _ 来规避
bs.find("div",class_="pic") # 返回第一个符合的 DOM 对象
bs.find_all() # 返回所有符合的 DOM list

# 精准定位 DOM 之后,可以用 get('class') 来获取属性值,用 .text 获取标签内容。
name = bs.text
class_ = bs.get('class')

XPath

基本用法

这个用来定位唯一的元素非常方便,这里使用 lxml 中的 etree (element tree) 来解析:

1
2
3
4
5
6
from lxml import etree

html = etree.HTML('') # 输入 HTML 字符串进行解析
html = etree.parse('') # 输入文件路径 URL,file 实例等解析为 DOM 对象

html.xpath('xxxxx') # 进行进一步的 xpath 格式匹配,返回还是 DOM 对象

XPath 语法

最简单的 XPath 是根据层次路径的元素名进行匹配的,如果有多个匹配的路径,就会全部被匹配,返回一个可迭代对象。

相同名称多个节点,可以用添加条件加以限制:

  • div[2] 来匹配第三个节点。
  • div[@class='click_to_sleep']div[@id='catalina'] 来指定 div 元素的 class 和 id 属性值。

通过 xpath 不停的精确匹配,可以用 ./ 表示当前 DOM 节点。


要获取 DOM 节点内容,匹配到节点之后,下一步用 /text(),返回字符串。

要获取 DOM 的属性值,匹配到节点之后,下一步用 /@class,返回属性 class 的字符串值。

异步加速

async await

见文章:Python-08

aiohttp

1
2
3
4
async with aiohttp.ClientSession() as session:
async with session.get(url, headers=Script.headers) as response:
content = await response.text(encoding='gbk')
content = await response.json()

aiofiles

1
2
async with aiofiles.open(fileName, mode='w',encoding='utf-8') as f:
await f.write(text)

Selenium 操作浏览器

下载对应浏览器的驱动,放置到脚本可以访问的 path 路径中,基本操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from selenium.webdriver import Edge
browser = Edge() # 创建浏览器对象
browser.get("https://www.baidu.com") # 访问目标网站

element = browser.find_element_by_xpath() # 定位元素并返回

element.click() # 对元素执行某种操作(假设为打开新窗口)

browser.close() # 关闭当前绑定窗口

browser.switch_to.window(browser.window_handles[-1]) # 将目前窗口切换到新的窗口上面

brower.close() # 关闭当前绑定窗口

反爬

验证人机

  1. 加上 user-agent 信息,模拟浏览器。
  2. 加上 Referer 信息,显示访问的上一级链接,模拟用户访问顺序。

代理

这里说一下代理的原理,至于使用方式在前面的 requests 模块介绍里。

web 知识

新页面渲染

当浏览器进行一个新页面渲染(刷新)的时候,默认会将以前的请求记录消除,所以可以点击 保留日志 选项,来保留以前的请求。

遇到一些关键请求隐藏在新页面渲染之前,可以通过这样的方式看到。

框架源代码

网页分为 页面源代码 和 框架源代码。页面源代码就是请求获取的 父页面。而框架源码就是父页面新请求出来的 iframe 的子页面。