友情提示本文章只用于学习不要用于非法活动!!
一、找接口
- 在百度里搜索关键词,右键点击检查
- 找到不同页的接口进行找规律
通过观察 pn 是不一样的从第一页 30 到第三页 90 得到规律为:页数 X30
在浏览器中可以看到 Word 是我们输入的关键字,因为 url 中的 word=的值是进行编码后的值 。
二、进行百度单线程代码的编写
- 进行编写查找每一页的 url 存放在 urls 里面代码。
if __name__ == '__main__':
word = input("请输入你要搜索的关键字:")
page_size = int(input("请输入爬取的页数:"))
star_time = datetime.now()
urls = [] # 把每一个接口地址放在urls中
for i in range(page_size):
# 得到每一页图片的url
url = f'https://image.baidu.com/search/acjson?tn=resultjson_com&logid=10516430500198415228&ipn=rj&ct=201326592&is=&fp=result&fr=&word={word}&cg=star&queryWord={word}&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=&z=&ic=&hd=&latest=©right=&s=&se=&tab=&width=&height=&face=&istype=&qc=&nc=1&expermode=&nojc=&isAsync=&pn={(i + 1) * 30}&rn=30&gsm=3c&1694950487982='
urls.append(url)
- 通过接口地址爬取图片
-
要想爬取到图片就要找到图片的 url,整张页面的 url 已经拿到了要在拿到的页面中找到图片的 url:thumbURL。
import json
import requestsdef down_imgs(url):
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'
}
# 如果服务端返回的是文本数据,就用text获取
# 如果服务端返回的是二进制数据(图片、音频、视频等)
# 就是content
res = requests.get(url, headers=header).text
# 将json字符串变成字典
dic = json.loads(res)
for item in dic["data"]:
# 获取图片地址
img_url = item.get("thumbURL", "") # 如果字典中没有thumURL就获取空字符串就不会报错
if img_url != "":
# 拿到图片数据
print(img_data)
- 进行图片的下载和存储,创建文件夹 file 使所有的图片都有一个唯一的文件名
import uuid
file_name = uuid.uuid4()
with open(f"pics/{file_name}.jpg", 'wb') as f:
f.write(img_data)
三、单线程爬取图片
- 单线程完整代码
import json
import uuid
import requests
from datetime import datetime
# 通过接口地址,爬取图片!!
def down_imgs(url):
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'
}
# 如果服务端返回的是文本数据,就用text获取
# 如果服务端返回的是二进制数据(图片、音频、视频等)
# 就是content
res = requests.get(url, headers=header).text
# 将json字符串变成字典
dic = json.loads(res)
for item in dic["data"]:
# 获取图片地址
img_url = item.get("thumbURL", "")
if img_url != "":
# 拿到图片数据
img_data = requests.get(img_url, headers=header).content
# wb 写入二进制数据
# 获取到一个全球唯一的文件名
file_name = uuid.uuid4()
with open(f"pics/{file_name}.jpg", 'wb') as f:
f.write(img_data)
if __name__ == '__main__':
word = input("请输入你要搜索的关键字:")
page_size = int(input("请输入爬取的页数:"))
star_time = datetime.now()
urls = [] # 把每一个接口地址放在urls中
for i in range(page_size):
# 得到每一页图片的url
url = f'https://image.baidu.com/search/acjson?tn=resultjson_com&logid=10516430500198415228&ipn=rj&ct=201326592&is=&fp=result&fr=&word={word}&cg=star&queryWord={word}&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=&z=&ic=&hd=&latest=©right=&s=&se=&tab=&width=&height=&face=&istype=&qc=&nc=1&expermode=&nojc=&isAsync=&pn={(i + 1) * 30}&rn=30&gsm=3c&1694950487982='
urls.append(url)
# 单线程代码
for url in urls:
down_imgs(url)
finish_time = datetime.now()
print(f"总共花费了{(finish_time-star_time).seconds}秒!")
四、多线程爬取图片
- 多线程相关代码代码
这里使用的线程为 5 个( max_workers=5),可以进行修改。
import json
import uuid
import requests
from datetime import datetime
from concurrent.futures import ThreadPoolExecutor
if __name__ == '__main__':
word = input("请输入你要搜索的关键字:")
page_size = int(input("请输入爬取的页数:"))
star_time = datetime.now()
urls = [] # 把每一个接口地址放在urls中
for i in range(page_size):
# 得到每一页图片的url
url = f'https://image.baidu.com/search/acjson?tn=resultjson_com&logid=10516430500198415228&ipn=rj&ct=201326592&is=&fp=result&fr=&word={word}&cg=star&queryWord={word}&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=&z=&ic=&hd=&latest=©right=&s=&se=&tab=&width=&height=&face=&istype=&qc=&nc=1&expermode=&nojc=&isAsync=&pn={(i + 1) * 30}&rn=30&gsm=3c&1694950487982='
urls.append(url)
# 多线程代码
with ThreadPoolExecutor(max_workers=5) as exe:
for url in urls:
exe.submit(down_imgs, url)
- 多线程完整代码
import json
import uuid
import requests
from datetime import datetime
from concurrent.futures import ThreadPoolExecutor
# 通过接口地址,爬取图片!!
def down_imgs(url):
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'
}
# 如果服务端返回的是文本数据,就用text获取
# 如果服务端返回的是二进制数据(图片、音频、视频等)
# 就是content
res = requests.get(url, headers=header).text
# 将json字符串变成字典
dic = json.loads(res)
for item in dic["data"]:
# 获取图片地址
img_url = item.get("thumbURL", "")
if img_url != "":
# 拿到图片数据
img_data = requests.get(img_url, headers=header).content
# wb 写入二进制数据
# 获取到一个全球唯一的文件名
file_name = uuid.uuid4()
with open(f"pics/{file_name}.jpg", 'wb') as f:
f.write(img_data)
if __name__ == '__main__':
word = input("请输入你要搜索的关键字:")
page_size = int(input("请输入爬取的页数:"))
star_time = datetime.now()
urls = [] # 把每一个接口地址放在urls中
for i in range(page_size):
# 得到每一页图片的url
url = f'https://image.baidu.com/search/acjson?tn=resultjson_com&logid=10516430500198415228&ipn=rj&ct=201326592&is=&fp=result&fr=&word={word}&cg=star&queryWord={word}&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=&z=&ic=&hd=&latest=©right=&s=&se=&tab=&width=&height=&face=&istype=&qc=&nc=1&expermode=&nojc=&isAsync=&pn={(i + 1) * 30}&rn=30&gsm=3c&1694950487982='
urls.append(url)
# 多线程代码
with ThreadPoolExecutor(max_workers=5) as exe:
for url in urls:
exe.submit(down_imgs, url)
finish_time = datetime.now()
print(f"总共花费了{(finish_time - star_time).seconds}秒!")
通过单线程和多线程的比较可以看出,多线程的下载速度非常快!