以百度-发现多彩世界为例
1.首先做的是分析网站
进入百度图片网站 页面如下:
可以看到,图中出现了我们想要爬取的图片,我们可以直接下载,但是,一张一张的下载是不是太浪费时间了些。因此,我们F12,进入到开发者选项当中。
如下图:
2.敲代码
1.获取headers
为了让网站认为我们的爬虫访问网站是人为的。我们需要获取一下headers,使用headers模拟人为访问网站,防止网站把我们的IP给down掉,造成我们无法访问网站的结果。
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0X-Requested-WithXMLHttpRequest=9'}
2.获取网页URL
经过分析,我们要访问网页初始网页,然后在初始界面找到目标网页的url,然后访问目标网页,并在网页里定位到具体的图片链接,之后我们就可以下载图片了
截图中的GET 后面的一串字符串,就是我们至关重要的URL,我们获取到了URL;
3.获取网页源代码
我们获取到了网页的url后,我们可以尝试获取网页源代码
我们先试试获取网页源代码:
import requests #导入模块
url = ' https://image.baidu.com/search/acjson?tn=resultjson_com&logid=8304085445139767441&ipn=rj&ct=201326592&is=&fp=result&fr=&word=玫瑰&queryWord=玫瑰&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&hd=&latest=©right=&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&expermode=&nojc=&isAsync=&pn=90&rn=30&gsm=5a&1639489219169='
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0X-Requested-WithXMLHttpRequest=9'}
response=requests.get(url,headers=headers)#访问网页
html=response.text
print(html)
输出结果 为网页源代码
3.获取图片链接
我们定位目标网页,并获取图片的链接
#爬取图片
from requests_html import HTMLSession
import requests#请求模拟 post get
import urllib
import json
from bs4 import BeautifulSoup#解析库
from PIL import Image
#1 第一次模拟请求 GET 请求 拿到必须的几项参数
session = requests.session()#为了保持代码中所有的session统一(会话控制)
url = """https://image.baidu.com/search/acjson?tn=resultjson_com&logid=8304085445139767441&ipn=rj&ct=201326592&is=&fp=result&fr=&word=玫瑰&queryWord=玫瑰&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&hd=&latest=©right=&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&expermode=&nojc=&isAsync=&pn=90&rn=30&gsm=5a&1639489219169="""
headers ={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.43'}
res = requests.get(url,headers=headers)#Get方式获取网页数据
#print(res.text)#输出网页链接
jsonInfo = json.loads(res.text)#使用json解码
for index in range(30):
print(jsonInfo['data'][index]['thumbURL'])
#soup = BeautifulSoup(res.text,'html.parser')#用html解析器来解析
#print(soup.select('img'))
获取网页链接后,我们就可以通过获取到的网页链接,访问到相应的图片
输出的结果,也就、是网页链接
https://img0.baidu.com/it/u=3790394977,1650517858&fm=26&fmt=auto
https://img1.baidu.com/it/u=1929383178,891687862&fm=26&fmt=auto
https://img0.baidu.com/it/u=82069894,371572825&fm=26&fmt=auto
https://img1.baidu.com/it/u=3143784284,2910826804&fm=26&fmt=auto
复制网页链接到浏览器,我们可以得到以下结果:
当然,我们要达到这个结果,至关重要的是,我们需要选获取,URL,
经过以上的分析,我们的编程思路也就清晰了
现在我们就可以进行编程了
总体代码如下:
#爬取图片
import requests#模拟请求
import json#轻量级的数据交换格式,易于人阅读和编写
from urllib import parse #用于url的解析,合并,编码,解码
import os#用于对文件进行操作了模块
import time#时间模块
class BaiduImageSpider(object):#创建一个类
def __init__(self):
self.directory = r"H:\Python\爬虫代码\第一个爬虫\images{}" # 存储目录 这里需要修改为自己希望保存的目录 {}不要丢
self.json_count = 0 # 请求到的json文件数量(一个json文件包含30个图像文件)
self.url = 'https://image.baidu.com/search/acjson?tn=resultjson_com&logid=5179920884740494226&ipn=rj&ct' \
'=201326592&is=&fp=result&queryWord={' \
'}&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&hd=&latest=©right=&word={' \
'}&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&expermode=&nojc=&pn={' \
'}&rn=30&gsm=1e&1635054081427= '
self.header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.30 '
}
# 获取图像链接
def get_image_link(self, url):
list_image_link = []#建立一个图像列表
strhtml = requests.get(url, headers=self.header) # Get方式获取网页数据
jsonInfo = json.loads(strhtml.text)#json.loads 将已编码的 JSON 字符串解码为 Python 对象
#获取图像的链接存到了列表中
for index in range(30):
#将jsonInfo中的数据放到列表中
list_image_link.append(jsonInfo['data'][index]['thumbURL'])#在列表末尾添加新的对象,将图像的链接放在列表中
return list_image_link
# 创建存储文件夹
def create_directory(self, name):
self.directory = self.directory.format(name)#补全文件夹名称
# 如果目录不存在则创建
if not os.path.exists(self.directory):#如果没有该路径
os.makedirs(self.directory)#使用os 模块创建该目录
self.directory += r'\{}'
# 下载图片
def save_image(self, img_link, filename):
#img_link为图像的链接
res = requests.get(img_link, headers=self.header)#模拟get请求 返回信息res 对象
if res.status_code == 404:
print(f"图片{img_link}下载出错------->")
with open(filename, "wb") as f:#使用二进制形式 覆盖写文件
f.write(res.content)#requests模块中的content返回的是二进制的数据
print("存储路径:" + filename)#打印存储路径
# 入口函数
def run(self):
name = input("你想要的图片:")
searchName_parse = parse.quote(name) # 编码 将中文转换为url编码格式
self.create_directory(name)#调用创建文件夹的函数,根据查询内容创建文件
pic_number = 0 # 图像数量
for index in range(self.json_count):
pn = (index+1)*30#pn表示一组文件,一组包含30个图像内容
#图像网页链接大部分相同,输入的url编码(serrchName_parse)不同,获取的图像类型不同
#通过不同的 url 编码获取新的链接
request_url = self.url.format(searchName_parse, searchName_parse, str(pn))
#str()函数将整数作为字符串,让其与两侧的字符串类型保持一致
list_image_link = self.get_image_link(request_url)#通过新的 url 调用图像链接函数,获取新的图像链接
for link in list_image_link:
pic_number += 1
self.save_image(link, self.directory.format(str(pic_number)+'.jpg'))
time.sleep(0.2) # 休眠0.2秒,防止封ip
print(name+"图像下载成功")
print("图片存入{}".format(self.directory))
if __name__ == '__main__':#代码作为模块,在别的文件调用时,不会直接运行整个脚本
spider = BaiduImageSpider()
spider.json_count = 1 # 默认下载一组图片(30张)
spider.run()