参考视频:2022年最新Python爬虫零基础教程
常用库:
- urllib.request -- 请求网页数据的模块,但被 requests 模块代替了
- requests -- 十分好用的请求网页数据的模块
- re -- 正则表达式模块
- bs4 -- 网页信息提取模块
- xpath -- 在 XML / HTML 中查找信息的模块
- pyquery -- 更加灵活的处理网页信息(可以修改网页信息)
- Thread -- 多线程
- ThreadPoolExecutor -- 线程池
- Process -- 多进程
- ProcessPoolExecutor -- 进程池
- asyncio -- 协程
- aiohttp -- 异步 http 请求库
- aiofiles -- 异步文件操作库
- selenium -- 自动化测试模块,模拟真人打开浏览器,主要是用来解决 JS 渲染的问题
- AJAX -- 动态页面数据抓取
库用法:
① requests
import requests
url = "xxx"
# GET
resp = requests.get(url, params=params)
print(resp.text) # 打印响应文
# POST
resp = requests.post(url, data=data)
print(resp.json()) # 返回 json 格式响应文时使用
# 部分参数
params = {
'wd': '中国'
}
data = {
'first': 'true',
'pn': '1',
'kd': 'Python'
}
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36'
}
# 部分用法
resp.url # 返回 url 地址
resp.encoding # 返回响应头部字符编码,准确性较低,省时
resp.apparent_encoding # 返回响应头部字符编码,准确性较高,耗时
resp.status_code # 返回响应码,200 为正常
type(resp.text) # str 类型
type(resp.content) # byte 类型
resp.text # 根据 resp.encoding 自动转换网页内容,准确性较低
resp.content # 显示网页原内容,即 byte 类型网页内容
resp.content.decode('utf-8') # 显示 str 类型网页内容
# Session 会话用法
session = requests.session()
# 模拟用户登入,一般步骤如下
1. session.post(URL1, data=data) # 模拟登入
2. print(resp.cookies) # 查看 Cookie
3. resp = session.get(URL2) # 访问目标网站
4. print(resp.text) # 查看访问内容
3. headers = {'Cookie': 'xxx'} # 也可以先在 URL1 网站存储 Cookie
4. resp = requests.get(URL2, headers=headers) # 直接访问目标网站
# Json 格式处理
# 此处省略获取 json 格式的请求,如 Video_Json = requests.get(VideoUrl, headers=headers).json()
Video_Json =
{
"resultCode": "1",
"resultMsg": "success",
"reqId": "30df5a33-a18a-492d-a8bd-22230ff9d7a0",
"systemTime": "1657678924851",
"videoInfo": {
"playSta": "1",
"video_image": "https://xxx.com/cont/xxx.png",
"videos": {
"hdUrl": "",
"hdflvUrl": "",
"sdUrl": "",
"sdflvUrl": "",
"srcUrl": "https://xxx.com/mp4/xxx.mp4"
}
}
}
# 获取 json 目标值
Target = Video_Json ['videoInfo']['videos']['srcUrl']
# https://xxx.com/mp4/xxx.mp4
# 下载图片格式 / 视频格式
PicUrl = xxx.png
with open("temp.jpg", mode="wb") as f:
f.write(requests.get(PicUrl).content)
VideoUrl = xxx.mp4
with open("temp.mp4", mode="wb") as f:
f.write(requests.get(VideoUrl).content)
② re
import re
# 基础用法
result = re.findall(r"\d+", "123我是筱团465啦啦啦789")
print(result)
# ['123', '465', '789']
# 迭代器,常用用法
result = re.finditer(r"\d+", "123我是筱团465啦啦啦789")
for item in result:
print(item.group())
# 123
# 465
# 789
# 只搜索第一个匹配项
result = re.search(r"\d+", "123我是筱团465啦啦啦789")
print(result.group())
# 123
# 只匹配从头开始能完全匹配的一个匹配项
result = re.match(r"\d+", "123我是筱团465啦啦啦789")
print(result.group())
# 123
# 预加载
obj = re.compile(r"\d+")
for i in data:
result = obj.finditer(content)
# 实操
# 想要提取数据必须用小括号括起来,可以单独起名字
# (?P<名字>正则表达式)
# 提取数据的时候,需要 group("名字")
data = """
<div class='西游记'><span id='10010'>中国联通</span></div>
<div class='西游记'><span id='10086'>中国移动</span></div>
"""
obj = re.compile(r"<span id='(?P<id>\d+)'>(?P<name>.*?)</span>")
result = obj.finditer(data)
for item in result:
id = item.group("id")
print(id)
name = item.group("name")
print(name)
# 10010
# 中国联通
# 10086
# 中国移动
③ bs4
from bs4 import BeautifulSoup
html = """
<ul>
<li><a href="zhangwuji.com">张无忌</a></li>
<li id="abc"><a href="zhouxingchi.com">周星驰</a></li>
<li><a href="zhubajie.com">猪八戒</a></li>
<li><a href="wuzetian.com">武则天</a></li>
<a href="jinmaoshiwang.com">金毛狮王</a>
</ul>
"""
page = BeautifulSoup(html, "html.parser")
# page.find("标签名", attrs={"属性": "值"}) # 查找某个元素, 只会找到一个结果
li = page.find("li", attrs={"id": "abc"})
# page.find_all("标签名", attrs={"属性": "值"}) # 查找到全部结果
li = page.find_all("li", attrs={"id": "abc"})
# 还可以通过 CSS 选择器进行查找,用法为 page.select(xxx)
# 继续查找标签中的内容
a = li.find("a")
# 获取文本
print(a.text)
# 获取属性
print(a.get("href"))
# 实操
li_list = page.find_all("li")
for li in li_list:
a = li.find("a")
text = a.text
href = a.get("href")
print(text, href)
"""
张无忌 zhangwuji.com
周星驰 zhouxingchi.com
猪八戒 zhubajie.com
武则天 wuzetian.com
"""
④ xpath
from lxml import etree
xml = """
<book>
<id>1</id>
<name>野花遍地香</name>
<price>1.23</price>
<nick>臭豆腐</nick>
<author>
<nick id="10086">周大强</nick>
<nick id="10010">周芷若</nick>
<nick class="jay">周杰伦</nick>
<nick class="jolin">蔡依林</nick>
<div>
<nick>惹了</nick>
</div>
</author>
<partner>
<nick id="ppc">胖胖陈</nick>
<nick id="ppbc">胖胖不陈</nick>
</partner>
</book>
"""
# 处理 XML
et = etree.XML(xml)
# / 表示根节点
result = et.xpath("/book")
# 在 xpath 中间的 / 表示的是儿子
result = et.xpath("/book/name")
# text() 拿文本
result = et.xpath("/book/name/text()")[0]
# 野花遍地香
# // 表示的是子孙后代.
result = et.xpath("/book//nick")
# * 表示通配符
result = et.xpath("/book/*/nick/text()")
# ['周大强', '周芷若', '周杰伦', '蔡依林', '胖胖陈', '胖胖不陈']
# [] 表示属性筛选 [@属性名=值]
result = et.xpath("/book/author/nick[@class='jay']/text()")
# ['周杰伦']
# 最后一个 / 表示拿到 nick 里面的 id 的内容,@属性 可以直接拿到属性值
result = et.xpath("/book/partner/nick/@id")
# ['ppc', 'ppbc']
html = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Title</title>
</head>
<body>
<ul>
<li><a href="http://www.baidu.com">百度</a></li>
<li><a href="http://www.google.com">谷歌</a></li>
<li><a href="http://www.sogou.com">搜狗</a></li>
</ul>
<ol>
<li><a href="feiji">飞机</a></li>
<li><a href="dapao">大炮</a></li>
<li><a href="huoche">火车</a></li>
</ol>
<div class="job">李嘉诚</div>
<div class="common">胡辣汤</div>
</body>
</html>
"""
# 处理 HTML
et = etree.HTML(html)
# 与处理 XML 类似,获取特定的文本内容
li = et.xpath("/html/body/ul/li[2]/a/text()")
# ['谷歌']
# // 表示直接选取目标属性
li_list = et.xpath("//li")
for li in li_list:
# ./ 表示当前节点
href = li.xpath("./a/@href")[0]
text = li.xpath("./a/text()")[0]
print(text, href)
"""
百度 http://www.baidu.com
谷歌 http://www.google.com
搜狗 http://www.sogou.com
飞机 feiji
大炮 dapao
火车 huoche
"""
⑤ pyquery
from pyquery import PyQuery
html = """
<ul>
<li class="aaa"><a href="http://www.google.com">谷歌</a></li>
<li class="aaa"><a href="http://www.baidu.com">百度</a></li>
<li class="bbb" id="qq"><a href="http://www.qq.com">腾讯</a></li>
<li class="bbb"><a href="http://www.yuanlai.com">猿来</a></li>
</ul>
"""
# 加载 html 内容
p = PyQuery(html)
# 打印 p 的内容
print(p)
"""
<ul>
<li class="aaa"><a href="http://www.google.com">谷歌</a></li>
<li class="aaa"><a href="http://www.baidu.com">百度</a></li>
<li class="bbb" id="qq"><a href="http://www.qq.com">腾讯</a></li>
<li class="bbb"><a href="http://www.yuanlai.com">猿来</a></li>
</ul>
"""
# 打印 p 的类型
print(type(p))
# <class 'pyquery.pyquery.PyQuery'>
# 选取目标标签,pyquery 对象直接(css 选择器)
a = p("a")
print(a)
# <a href="http://www.google.com">谷歌</a><a href="http://www.baidu.com">百度</a><a href="http://www.qq.com">腾讯</a><a href="http://www.yuanlai.com">猿来</a>
# 打印 a 的类型,依然是 pyquery 对象
print(type(a))
# <class 'pyquery.pyquery.PyQuery'>
# 链式操作
a = p("li")("a")
print(a)
# <a href="http://www.google.com">谷歌</a><a href="http://www.baidu.com">百度</a><a href="http://www.qq.com">腾讯</a><a href="http://www.yuanlai.com">猿来</a>
# 打印二层标签
a = p("li a")
print(a)
# <a href="http://www.google.com">谷歌</a><a href="http://www.baidu.com">百度</a><a href="http://www.qq.com">腾讯</a><a href="http://www.yuanlai.com">猿来</a>
# 打印类为 aaa 的标签(class="aaa"),二层标签为 a 的值
a = p(".aaa a")
print(a)
# <a href="http://www.google.com">谷歌</a><a href="http://www.baidu.com">百度</a>
# 打印 id 为 qq 的标签(id="qq"),二层标签为 a 的值
a = p("#qq a")
print(a)
# <a href="http://www.qq.com">腾讯</a>
# 打印 id 为 qq 的标签(id="qq"),二层标签为 a 的属性
href = p("#qq a").attr("href")
print(href)
# http://www.qq.com
# 打印 id 为 qq 的标签(id="qq"),二层标签为 a 的文本
text = p("#qq a").text()
print(text)
# 腾讯
# 如果多个标签同时拿属性 [attr]. 只能默认拿到第一个
href = p("li a").attr("href")
print(href)
# http://www.google.com
# 多个标签拿属性
it = p("li a").items()
for item in it: # 从迭代器中拿到每一个标签
href = item.attr("href") # 拿到 href 属性
text = item.text()
print(text, href)
"""
谷歌 http://www.google.com
百度 http://www.baidu.com
腾讯 http://www.qq.com
猿来 http://www.yuanlai.com
"""
'''
快速总结:
1. pyquery(选择器)
2. items() 当选择器选择的内容很多的时候. 需要一个一个处理的时候
3. attr(属性名) 获取属性信息
4. text() 获取文本
'''
html = """
<div><span>我爱你</span></div>
"""
p = PyQuery(html)
html = p("div").html() # 全都要
text = p("div").text() # 只要文本, 所有的 html 标签被过滤掉
print(html)
print(text)
"""
<span>我爱你</span>
我爱你
"""
html = """
<HTML>
<div class="aaa">哒哒哒</div>
<div class="bbb">嘟嘟嘟</div>
</HTML>
"""
p = PyQuery(html)
# 在 xxx 标签后面添加 xxx 新标签
p("div.aaa").after("""<div class="ccc">吼吼吼</div>\n""")
print(p)
"""
<HTML>
<div class="aaa">哒哒哒</div>
<div class="ccc">吼吼吼</div>
<div class="bbb">嘟嘟嘟</div>
</HTML>
"""
# 在 xxx 标签中间添加 xxx 新标签
p("div.aaa").append("""<span>我爱你</span>""")
print(p)
"""
<HTML>
<div class="aaa">哒哒哒<span>我爱你</span></div>
<div class="ccc">吼吼吼</div>
<div class="bbb">嘟嘟嘟</div>
</HTML>
"""
# 修改属性
p("div.bbb").attr("class", "ddd")
print(p)
"""
<HTML>
<div class="aaa">哒哒哒<span>我爱你</span></div>
<div class="ccc">吼吼吼</div>
<div class="ddd">嘟嘟嘟</div>
</HTML>
"""
# 新增属性,前提是该标签没有这个属性
p("div.ddd").attr("id", "123456")
print(p)
"""
<HTML>
<div class="aaa">哒哒哒<span>我爱你</span></div>
<div class="ccc">吼吼吼</div>
<div class="ddd" id="123456">嘟嘟嘟</div>
</HTML>
"""
# 删除属性
p("div.ddd").remove_attr("id")
print(p)
"""
<HTML>
<div class="aaa">哒哒哒<span>我爱你</span></div>
<div class="ccc">吼吼吼</div>
<div class="ddd">嘟嘟嘟</div>
</HTML>
"""
# 删除标签
p("div.ddd").remove()
print(p)
"""
<HTML>
<div class="aaa">哒哒哒<span>我爱你</span></div>
<div class="ccc">吼吼吼</div>
</HTML>
"""
# 小总结:p 可以直接修改 html 的内容,且可以永久修改
⑥ Thread,ThreadPoolExecutor,Process
⑦ asyncio,aiohttp,aiofiles
详情参考: python 高级用法 -- 进程、线程和协程
⑧ selenium
Chrome 内核下载
from selenium.webdriver import Chrome
from selenium.webdriver.support import expected_conditions as EC # 等待操作需要导入的库
from selenium.webdriver.common.action_chains import ActionChains # 用于完成一系列操作
from selenium.webdriver.support.wait import WebDriverWait # 等待某个特定的操作
from selenium.webdriver.chrome.options import Options # 设置参数
from selenium.webdriver.support.select import Select # 专门用于处理下拉框
from selenium.webdriver.common.keys import Keys # 所有按键的指令
from selenium.webdriver.common.by import By # 指定搜索方法
"""
两个前置条件:
1. 部分代码仅适用于 Chrome 内核
2. Chrome 驱动器需放置在 Python 编译器同目录下
"""
# 内核驱动参数
options = Options()
# 处理 SSL 证书错误问题、隐藏自动化操作、忽略无用的日志、禁用 GPU(默认添加)
options.add_argument('--ignore-certificate-errors')
options.add_argument('--ignore-ssl-errors')
options.add_argument('--disable-blink-features=AutomationControlled')
options.add_experimental_option("excludeSwitches", ['enable-automation', 'enable-logging'])
options.add_argument('--disable-gpu')
# 使用代理,防止被 gank
options.add_argument('--proxy-server=http://120.220.220.95:8085')
# 无头浏览器,窗口调大,防止样式堆叠
options.add_argument("--headless")
options.add_argument("--window-size=4000,1600")
# 初始化
web = Chrome(options=options)
# 进入网站
web.get("http://www.baidu.com")
# 全局隐式等待 5 秒,即获取元素的函数超过 5 秒就报错超时
web.implicitly_wait(5)
# 窗口最大化
web.maximize_window()
# 切换到最新窗口(最旧窗口是 [0] / 最新窗口是 [-1])
web.switch_to.window(web.window_handles[-1])
# 关闭当前窗口
web.close()
# 切换到 iframe 中
web.switch_to.frame(iframe)
# 切换到上层 iframe
web.switch_to.parent_frame()
# 关闭整个驱动
web.quit()
# 获取窗口标题
title = web.title
# 获取目标元素(By.XPATH / By.CSS_SELECTOR / By.CLASS_NAME / By.ID)
element = web.find_element(By.XPATH, "//div[@class='job']/li")
elements = web.find_elements(By.CSS_SELECTOR, "div > button[type='submit']")
# 获取目标元素,若超过 10 秒就报错超时(不同于全局隐式等待,仅作用于特定函数)
elements = WebDriverWait(web, 10, 0.5).until(EC.presence_of_element_located((By.XPATH, "//div[@class='job']/li")))
# 获取元素文本内容
text = element.text
# 获取元素属性(@)
href = element.get_attribute("class")
href = element.get_property("href")
# 获取 cookies 列表,需要手动转换为字典
cookies = web.get_cookies()
# 元素框输入内容(Keys.ENTER / Keys.TAB / Keys.SPACE / Keys.BACK_SPACE)(仅使用于 input 标签)
element.send_keys("python") # send_keys("python", Keys.ENTER)
# 点击元素
element.click()
# 获取选择框元素(仅使用于 select 标签)
select = Select(element)
for option in select.options: # 列出全部选项
select.select_by_visible_text(option.text) # 通过文字切换到目标选项
# 截图,获得图片字节(仅使用于 img 标签)
bs = img.screenshot_as_png
# 存储图片至文件中(适合存储 png 文件)
img.screenshot("pic.png")
# 事件链,用于连续完成一系列事件(最后一定要执行 perform 函数)
ActionChains(web).click_and_hold(button).move_by_offset(0, 300).perform()
"""
# 可以用如下代码获取 cookies 字典
cookies = web.get_cookies()
_cookies = {}
for cookie in cookies:
_cookies[cookie['name']] = cookie['value']
cookies = _cookies
"""
正则表达式用法:
常用元字符:具有固定含义的特殊符号
. 匹配除换行符以外的任意字符,未来在python的re模块中是一个坑
\w 匹配字母或数字或下划线
\s 匹配任意的空白符
\d 匹配数字
\n 匹配一个换行符
\t 匹配一个制表符
^ 匹配字符串的开始
$ 匹配字符串的结尾
\W 匹配非字母或数字或下划线
\D 匹配非数字
\S 匹配非空白符
a|b 匹配字符 a 或字符 b
() 匹配括号内的表达式,也表示一个组
[...] 匹配字符组中的字符
[^...] 匹配除了字符组中字符的所有字符
量词:控制前面的元字符出现的次数
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复 n 次
{n,} 重复 n 次或更多次 PS: {0,} 相当于 * / {1,} 相当于 +
{n,m} 重复 n 到 m 次
贪婪匹配和惰性匹配
.* 贪婪匹配,尽可能多的去匹配结果
.*? 惰性匹配,尽可能少的去匹配结果 --> 回溯
HTML 基础语法规则:
1. <标签名 属性="值">被标记的内容</标签名>
2. <标签名 属性="值" />
3. <!-- 注释内容 -->
4. 实例如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我是标题</title>
</head>
<body bgcolor="pink">
<h1 align="right">我爱周润发</h1>
<p>周润发同志. 曾经是一个赌神. 我特别崇拜他</p>
<a href="http://www.baidu.com">周润发的个人主页</a>
<img src="abc.jpg" width="50px" height="60px" />
</body>
</html>
XML 基础语法规则:
XML 和 HTML 的区别:
1. HTML 中的标记是用来显示数据的,而 XML 中的标记用来描述数据的性质和结构
2. HTML 是不区分大小写的,而 XML 是严格区分大小写的
3. HTML 可以有多个根元素,而格式良好的 XML 有且只能有一个根元素
4. HTML 中,内容中的空格是自动过滤的,而 XML 中,空格则不会自动删除
5. 实例如下
<book>
<id>1</id>
<name>野花遍地香</name>
<price>1.23</price>
<nick>臭豆腐</nick>
<author>
<nick id="10086">周大强</nick>
<nick id="10010">周芷若</nick>
<nick class="jay">周杰伦</nick>
<nick class="jolin">蔡依林</nick>
<div>
<nick>惹了</nick>
</div>
</author>
<partner>
<nick id="ppc">胖胖陈</nick>
<nick id="ppbc">胖胖不陈</nick>
</partner>
</book>
CSS 基础语法规则:
1. 通过 style 属性来编写样式
<div style="width:100px;height:100px;border: 1px solid red;">你好, 我叫周润发</div>
2. 通过 style 标签. 然后使⽤选择器的形式来编写样式
<head>
<style>
span {
color: pink;
}
</style>
</head>
3. 在 css ⽂件中编写样式, 通过 link 引⼊该⽂件
<head>
<link rel="stylesheet" href="mycss.css">
</head>
CSS 选择器:
1. id 选择器 #
2. 标签选择器 标签
3. 类选择器 .
4. 选择器分组 ,
5. 后代选择器 空格
6. 子选择器 >
7. 相邻选择器 +
8. 属性选择器 [属性=值]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#abc {
color: pink;
}
li {
border: 1px solid red;
}
.jay {
color: green;
}
div, span {
background: hotpink;
}
ul li {
/* 空格表示子子孙孙, 所有后代 */
list-style: none;
}
ul>li {
/* > 表示儿子一层 */
list-style: none;
}
h1+h2 {
color: red;
}
a[target] {
color: green;
}
a[target='_blank'] {
text-decoration: none;
}
</style>
</head>
<body>
<!--
<ul>
<li>周润发</li>
<li id="abc">黎明</li>
<li>周星驰</li>
<li>
<ol>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ol>
</li>
</ul>
<ol>
<li>手电筒</li>
<li>电视机</li>
<li>黑板擦</li>
</ol>
<div class="jay">呵呵哒</div>
<span class="jay">呵呵哒</span>
<h1>我爱麻花藤</h1>
<h2>我爱黎明</h2>
<h2>我也爱黎明</h2>
-->
<a href="#" target="_blank">我是blank</a>
<a href="#" target="_self">我是self</a>
<a href="#">我是啥也没有</a>
</body>
</html>
IP 代理池:
# 使用单个代理
proxy = {
"http": "http://182.84.144.66:3256/"
# "https": "https://182.84.144.66:3256/"
}
resp = requests.get(URL, proxies=proxy)
# 使用代理池(快代理为例)
def get_ip():
# 反复提取代理 ip
while 1:
# 快代理的 ip 池
url = "https://ent.kdlapi.com/api/getproxy/xxx"
resp = requests.get(url)
ips = resp.json()
if ips['code'] == 0:
for ip in ips['data']['proxy_list']: # 拿到每一个 ip
print("正在使用的代理ip:", ip)
yield ip # 一个一个返回代理 ip
print("所有 ip 已经用完, 即将更新!") # for 循环结束,继续提取新 ip
else:
print("获取代理 ip 出现异常,重新获取!")
def spider():
URL = "https://www.xxx.com"
while 1:
try:
proxy_ip = next(gen) # 拿到代理 ip
# 不清楚为什么,加上 https 的代理似乎用不了
# proxies = {"http": proxy_ip, "https": proxy_ip}
proxies = {"http": proxy_ip}
# print(proxies)
# 设置 20 秒超时
resp = requests.get(URL, proxies=proxies, timeout=20)
# xxxxx
# xxxxx
return None # 运行成功后,强制返回
except:
print("报错了")
if __name__ == '__main__':
gen = get_ip() # 代理 ip 的生成器
spider()
图形验证码识别:
图形验证码识别网站 1:超级鹰
#! /usr/bin/env python
# -*- coding: UTF-8 -*-
import requests
from hashlib import md5
class Chaojiying_Client(object):
"""
超级鹰自带的类,调用即可
"""
def __init__(self, username, password, soft_id):
self.username = username
password = password.encode('utf8')
self.password = md5(password).hexdigest()
self.soft_id = soft_id
self.base_params = {
'user': self.username,
'pass2': self.password,
'softid': self.soft_id,
}
self.headers = {
'Connection': 'Keep-Alive',
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
}
def PostPic(self, im, codetype):
"""
im: 图片字节
codetype: 题目类型 参考 http://www.chaojiying.com/price.html
"""
params = {
'codetype': codetype,
}
params.update(self.base_params)
files = {'userfile': ('ccc.jpg', im)}
r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
return r.json()
def PostPic_base64(self, base64_str, codetype):
"""
im: 图片字节
codetype: 题目类型 参考 http://www.chaojiying.com/price.html
"""
params = {
'codetype': codetype,
'file_base64':base64_str
}
params.update(self.base_params)
r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, headers=self.headers)
return r.json()
def ReportError(self, im_id):
"""
im_id:报错题目的图片ID
"""
params = {
'id': im_id,
}
params.update(self.base_params)
r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
return r.json()
if __name__ == '__main__':
chaojiying = Chaojiying_Client('137270xxxxx', 'LLxxxxx', '939271') # 用户名 / 密码 / 软件ID
img_path = open('a.jpg', 'rb').read() # 读取本地图片
result = chaojiying.PostPic(img_path, 1004) # 验证码类型,详情见超级鹰价格体系
'''
img = web.find_element(By.XPATH, '//div/img') # 读取网络图片,标签为 img
bs = img.screenshot_as_png # 截图,获得图片字节
result = chaojiying.PostPic(bs, 1004)
'''
code = result['pic_str'] # 识别结果
print(result) # 打印结果
图形验证码识别网站 2:图鉴(推荐)
#! /usr/bin/env python
# -*- coding: UTF-8 -*-
import base64
import json
import requests
def base64_api(uname, pwd, img, typeid):
"""
图鉴自带的类,调用即可
"""
if(type(img) == type("str")): # 传入图片路径
with open(img, 'rb') as f:
base64_data = base64.b64encode(f.read())
b64 = base64_data.decode()
else: # 传入图片字节
base64_data = base64.b64encode(img)
b64 = base64_data.decode()
data = {"username": uname, "password": pwd, "typeid": typeid, "image": b64}
result = json.loads(requests.post("http://api.ttshitu.com/predict", json=data).text)
if result['success']:
return result["data"]["result"]
else:
return result["message"]
if __name__ == "__main__":
img_path = "pic.png" # 读取本地图片
result = base64_api(uname='tuanzi', pwd='LLxxxxx', img=img_path, typeid=3) # 用户名 / 密码 / 图片类型
'''
img = web.find_element(By.XPATH, '//div/img') # 读取网络图片,标签为 img
bs = img.screenshot_as_png # 截图,获得图片字节
result = base64_api(uname='tuanzi', pwd='LLxxxxx', img=bs, typeid=3)
'''
print(result) # 打印结果
爬虫思路:
# 有条有理有步骤
def spider():
url = "xxx"
resp = requests.get(url, proxies=proxy, timeout=20)
resp.encoding = "utf-8"
return resp.text
# 使用 Postman 测试抓单个包是否能正常响应
# 分析网站的源代码(存储本地)
f = open("./reference.html", mode="w", encoding='utf-8')
resp = requests.get('https://www.xxx.com')
resp.encoding = 'utf-8'
f.write(resp.text)
f.close()
# 分析网站的源代码(本地分析)
f = open("./reference.html", mode="r", encoding='utf-8')
data = f.read()
f.close()