因为最近做了一个小型app,关于图像识别方向的,所以需要很多图片做数据集,一个个下载太慢了,所以就研究写了一个简单的小爬虫,就想着把这些经验记录下来,每一个网站的html结构都是不同的,所以对于不同的网站需要做出相应的更改,读这篇可能需要一些前端知识,总代码我发在最后了
这里用一个服装网站当作例子 (用哪个网站都可以,主要的是方法和代码)==》 https://www.black-up.kr/product/detail.html?product_no=32474&cate_no=96&display_group=1
import requests
from bs4 import BeautifulSoup
import os
我们需要准备一个浏览器的请求头,他是一个字典的形式,爬虫的本质就是利用请求头伪装成浏览器然后去进行访问,每个浏览器的请求头格式又不太一样,但是内容是一样的,我们要将请求头变为字典的形式,这里我写了一个小脚本可以帮助格式化请求头,但是可能只限于我用的edge浏览器,如果你不同浏览器也可以试试这个脚本,你也可以手动给他格式化就是麻烦一点
获取步骤如下:
1)打开浏览器进入目标网址(我用的是edge浏览器),按F12进入后台,点击网络,找到名称列表最上面的一条也就是第一条,在标头的位置也就是右方滚轮向下滑,可以看到请求标头四个字,从Accept开始复制,一直复制到最后面的user-agent,Accept前面都不需要
将复制的请求头进行格式化
格式化代码如下:
headerStr这个长字符串里面的内容就是刚才复制的请求头,你只需要将headerStr里面的内容删除换成你自己复制的请求头即可
注意:headerStr里面的未格式化的请求头最好和下面的位置一样,顶头复制,不要在Accept这些属性前面留有空格什么的
import re
def formulate_head():
header_lines_value = ''
headerStr = '''
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding:
gzip, deflate, br
Accept-Language:
zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Cookie:
_gcl_au=1.1.511254458.1684805008; CUK45=cuk45_skfo900815_4d9322403b6cab3d50371082910e0531; CUK2Y=cuk2y_skfo900815_4d9322403b6cab3d50371082910e0531; _fbp=fb.1.1684805009113.971249844; black-up.kr-crema_device_token=LzzlyHO6YLN0keIv2jauEH73Xy2PRdBz; CFAE_CUK1Y=CFAE_CUK1Y.skfo900815_1.PZPJ94T.1684805009865; ch-veil-id=dafe7ccc-ecc3-43cd-ade9-bfcb8e1187dd; _wp_uid=2-45d93ef5ddc801f3dc97e1ec636ad20b-s1684809260.904994|windows_10|chrome-eqdzf9; _ga=GA1.2.1044427573.1684823556; recent_plist=31429%7C31417%7C31495%7C31421%7C31458%7C31211; wcs_bt=s_47112a8eb19a:1686401209; cto_bundle=k7_3Fl9saEF4MGhSelVRU3EwVDFZMElMRXZCdHpEZUk0WnNFcG5GRG5lS3dGJTJCSkIydXM5aXlHdnglMkJ5JTJGdFJ3QkxMYTRKRjdkYnJQcHA2eVp4U1lTbUFscXlvOHU2VHduaCUyQldHQXhLR3BJNmp5dFlKVXJGcUdPejZmVTNRV24xOXlMU3JGdmhKY3BBZnFKSVMwZEIzRCUyRm11SW93JTNEJTNE
Sec-Ch-Ua:
"Not/A)Brand";v="99", "Microsoft Edge";v="115", "Chromium";v="115"
Sec-Ch-Ua-Mobile:
?0
Sec-Ch-Ua-Platform:
"Windows"
Sec-Fetch-Dest:
document
Sec-Fetch-Mode:
navigate
Sec-Fetch-Site:
none
Sec-Fetch-User:
?1
Upgrade-Insecure-Requests:
1
User-Agent:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.188
'''
header_lines = headerStr.strip().split('\n')
# print(header_lines)
# exit()
ret = ""
jump = 0
for i in range(jump,len(header_lines)):
if i >= jump:
if header_lines[i].rfind(':') != -1:
ret += '\'' + header_lines[i] + ' ' + header_lines[i+1] + '\'' + ',\n'
jump = i+2
ret = re.sub(": ", "': '", ret)
ret = ret[:-2]
print(ret)
return ret
formulate_head()
运行上面的代码,结果如下,可以看到已经都被格式化为字典的形式了,将生成的结果复制下来,放到参数中
将格式化后的headers放入字典中即可
if __name__ == '__main__':
# 爬虫网址
url = "https://www.black-up.kr/product/detail.html?product_no=32474&cate_no=96&display_group=1"
# 文件命名
pic_name = "download_pic_"
# 保存文件目录
save_dir = "D:\lableimg1.8\csdn\spider_pic"
# 请求头
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'Cookie': '_gcl_au=1.1.511254458.1684805008; CUK45=cuk45_skfo900815_4d9322403b6cab3d50371082910e0531; CUK2Y=cuk2y_skfo900815_4d9322403b6cab3d50371082910e0531; _fbp=fb.1.1684805009113.971249844; black-up.kr-crema_device_token=LzzlyHO6YLN0keIv2jauEH73Xy2PRdBz; CFAE_CUK1Y=CFAE_CUK1Y.skfo900815_1.PZPJ94T.1684805009865; ch-veil-id=dafe7ccc-ecc3-43cd-ade9-bfcb8e1187dd; _wp_uid=2-45d93ef5ddc801f3dc97e1ec636ad20b-s1684809260.904994|windows_10|chrome-eqdzf9; _ga=GA1.2.1044427573.1684823556; recent_plist=31429%7C31417%7C31495%7C31421%7C31458%7C31211; wcs_bt=s_47112a8eb19a:1686401209; cto_bundle=k7_3Fl9saEF4MGhSelVRU3EwVDFZMElMRXZCdHpEZUk0WnNFcG5GRG5lS3dGJTJCSkIydXM5aXlHdnglMkJ5JTJGdFJ3QkxMYTRKRjdkYnJQcHA2eVp4U1lTbUFscXlvOHU2VHduaCUyQldHQXhLR3BJNmp5dFlKVXJGcUdPejZmVTNRV24xOXlMU3JGdmhKY3BBZnFKSVMwZEIzRCUyRm11SW93JTNEJTNE',
'Sec-Ch-Ua': '"Not/A)Brand";v="99", "Microsoft Edge";v="115", "Chromium";v="115"',
'Sec-Ch-Ua-Mobile': '?0',
'Sec-Ch-Ua-Platform': '"Windows"',
'Sec-Fetch-Dest': 'document',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'none',
'Sec-Fetch-User': '?1',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.188'}
get_content_black(url,pic_name,save_dir,headers)
requests.get(url,headers)就代表获取网站信息,url代表网址,headers代表上面的请求头,返回的response.status_code会保存状态码,200即为访问成功,其他则为失败
response = requests.get(url, headers=headers)
if response.status_code != 200:
print('访问失败')
return
if response.status_code == 200:
print('访问成功')
beautifulSoup()将response返回的html结构转化成lxml的格式,方便后续进行操作
html = BeautifulSoup(response.content, 'lxml')
print(html) # 查看html
打印出来的html如下:
接下来就可以像操纵数组一样还获取html中的内容
1) 首先你要找到你目标位置的html结构,比如你想要这个卖衣服网站的细节图,操作如下:
还是按F12切出后台,点击上面带有鼠标箭头的按钮,然后点击图片,这时候右边就会显示出这个图片所在的html结构,可以看出这些细节图片都是封装在一个名为detailArea的类下面,而这图片地址本身又是封装在一个img标签的src属性之中,那么知道这些就够了
2) 代码寻找结构
先通过.find_all找到类名为detailArea的里面的所有标签信息
content = html.find_all('div', class_="detailArea")
print(content)
打印结果如下:
发现里面有我们想要的img标签,里面也正好是细节图,自己可以对照一下,下一步就很明确了,通过find_all再抽取出所有img标签,这里用content[0]是因为上一步返回的其实就是一个列表格式(注意看上面图片的方括号),而这个列表又只有一个元素(因为只找到一个detailArea类名,如果有多个detailArea的div类就会有多个元素了,列表用逗号分隔),虽然很长,但是调用的时候也得取第一个元素所以就出现了content[0]
pics = content[0].find_all('img') # 第一个子集
print(pics)
打印结果如下:
可以看到因为detailArea这个类下有多个img标签返回的也是列表形式,所以下一步就是对这个列表进行for循环取出所有的src值
利用for循环取出每一个src等于号后面的值,再拼接上网址的表头,再将拼接好的网址信息依次放入一个新列表中,这时候新列表中存储的就都是图片的链接地址了
# 循环获得子集里img的键值对
for i in pics:
pic_url = 'https://www.black-up.kr/' + i['src']
pic_urls.append(pic_url)
列表打印结果如下:
最后一步就是对图片进行下载和保存了,代码如下:
requests.get(url,headers)这个方法是用来下载网址内容的,参数url代表网址,headers就是一直用的请求头,因为每个图片的网站都不同,所以每次都要判断一下status_code是否为200也就是是否访问成功,访问成功就代表图片下载成功了,接下来就设置文件名并将保存路径和文件名拼接在一起,最后保存到本地即可
num = 0
for each_img_url in pic_urls:
response = requests.get(each_img_url, headers=headers)
# print(response.status_code)
# exit()
if response.status_code == 200:
# 获取文件名
file_name = pic_name + str(num) + '.jpg'
num = num + 1
# 拼接保存图片的完整路径
save_path = os.path.join(save_dir, file_name)
# 保存图片到本地
with open(save_path, 'wb') as file:
file.write(response.content)
print(f'图片已保存为 {file_name}')
# print(f'图片已保存为 {file_name}')
else:
print('无法下载图片')
print(f'保存完毕')
运行截图如下:
到这就全部结束了,说点番外的,如果你想取一些特定的信息,比如特定的图片,就可以看一下这个图片的html结构与其他图片html结构的区别,然后用一些if条件给他分离出来就行了,一个熟能生巧的过程,用代码的时候别忘了headers用自己的然后格式化一下,要说的就这么多了,全部代码我放下面了,如果还有什么没懂的或者有困难的也可以邮箱联系我,大家一起进步 [email protected]
import requests
from bs4 import BeautifulSoup
import os
def get_content_black(url, pic_name, save_dir, headers):
pic_urls = []
response = requests.get(url, headers=headers)
if response.status_code != 200:
print('访问失败')
return
if response.status_code == 200:
print('访问成功')
# print(response) # 查看是否请求成功
print("**开始获取图片**")
html = BeautifulSoup(response.content, 'lxml')
# print(html) # 查看html
content = html.find_all('div', class_="detailArea") # class为detail的子集
# print(content)
first_single = html.find_all('div', class_="keyImg") # 首页第一个照片
# print(first_single)
first_single_a = first_single[0].find_all('a') # 获取a标签
first_single_a_i = first_single_a[0].find_all('img') # 进入img标签
first_single_src = first_single_a_i[0]['src'] # 取键值对
first_single_src = 'https:' + first_single_src
# first_single_src = first_single_src.replace("//", "", 1) # 删除字符串开头的//
pic_urls.append(first_single_src) # 添加到数组中
# print(first_single_src)
pics = content[0].find_all('img') # 第一个子集
# print(pics)
# 循环获得子集里img的键值对
for i in pics:
pic_url = 'https://www.black-up.kr/' + i['src']
pic_urls.append(pic_url)
# print(pic_url)
# print(pic_urls)
if len(pic_urls) == 0:
print(f'图片获取失败')
return
print(f'图片获取成功')
# 下面是下载图片
num = 0
for each_img_url in pic_urls:
response = requests.get(each_img_url, headers=headers)
# print(response.status_code)
# exit()
if response.status_code == 200:
# 获取文件名
file_name = pic_name + str(num) + '.jpg'
num = num + 1
# 拼接保存图片的完整路径
save_path = os.path.join(save_dir, file_name)
# 保存图片到本地
with open(save_path, 'wb') as file:
file.write(response.content)
print(f'图片已保存为 {file_name}')
else:
print('无法下载图片')
print(f'保存完毕')
return pic_urls
if __name__ == '__main__':
# 爬虫网址
url = "https://www.black-up.kr/product/detail.html?product_no=32474&cate_no=96&display_group=1"
# 文件命名
pic_name = "download_pic_"
# 保存文件目录
save_dir = "D:\lableimg1.8\csdn\spider_pic"
# 请求头
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'Cookie': '_gcl_au=1.1.511254458.1684805008; CUK45=cuk45_skfo900815_4d9322403b6cab3d50371082910e0531; CUK2Y=cuk2y_skfo900815_4d9322403b6cab3d50371082910e0531; _fbp=fb.1.1684805009113.971249844; black-up.kr-crema_device_token=LzzlyHO6YLN0keIv2jauEH73Xy2PRdBz; CFAE_CUK1Y=CFAE_CUK1Y.skfo900815_1.PZPJ94T.1684805009865; ch-veil-id=dafe7ccc-ecc3-43cd-ade9-bfcb8e1187dd; _wp_uid=2-45d93ef5ddc801f3dc97e1ec636ad20b-s1684809260.904994|windows_10|chrome-eqdzf9; _ga=GA1.2.1044427573.1684823556; recent_plist=31429%7C31417%7C31495%7C31421%7C31458%7C31211; wcs_bt=s_47112a8eb19a:1686401209; cto_bundle=k7_3Fl9saEF4MGhSelVRU3EwVDFZMElMRXZCdHpEZUk0WnNFcG5GRG5lS3dGJTJCSkIydXM5aXlHdnglMkJ5JTJGdFJ3QkxMYTRKRjdkYnJQcHA2eVp4U1lTbUFscXlvOHU2VHduaCUyQldHQXhLR3BJNmp5dFlKVXJGcUdPejZmVTNRV24xOXlMU3JGdmhKY3BBZnFKSVMwZEIzRCUyRm11SW93JTNEJTNE',
'Sec-Ch-Ua': '"Not/A)Brand";v="99", "Microsoft Edge";v="115", "Chromium";v="115"',
'Sec-Ch-Ua-Mobile': '?0',
'Sec-Ch-Ua-Platform': '"Windows"',
'Sec-Fetch-Dest': 'document',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'none',
'Sec-Fetch-User': '?1',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.188'}
get_content_black(url,pic_name,save_dir,headers)