本文共 3213 字,大约阅读时间需要 10 分钟。
在实际开发中,当我们需要批量爬取百度图片时,经常会遇到“瀑布流”或“分页模式”的问题。百度图片采用瀑布流方式加载图片,这意味着每次加载的图片数量有限,为了实现完整的图片抓取,需要对请求头进行调整,切换为分页模式。
当我们观察百度图片页面的网页源代码时,会发现请求地址中带有“flip”参数。这是瀑布流模式的特征,用于实现无限滚动加载。为了实现分页模式,我们可以通过修改请求头中的“flip”参数值来实现对不同页面的请求。
在实际应用中,可以通过以下方式实现:
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36', # 模拟无限滚动,实现分页效果 'X-Flip': '0'} 此时,请求地址会随着flip参数的改变而变化,从而实现分页效果。
通过观察百度图片的网页源代码,可以发现图片的URL地址被嵌入在网页中。具体的提取方式如下:
import requestsfrom bs4 import BeautifulSoupimport re# 目标图片链接target_url = 'https://image.baidu.com/search/flip?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1619608652857_R&pv=&ic=&nc=1&hd=&latest=©right=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&sid=&word=关键词'headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36',}response = requests.get(target_url, headers=headers)text = response.text# 提取图片URL地址picture_urls = re.findall(r'"objURL":"(.*?)"', text) 在实际应用中,图片的URL地址可能会因为百度的防爬机制而发生变化。因此,我们需要对图片地址进行一定的处理,确保能够正常获取到图片资源。
以下是一些常见的处理方法:
文件名提取:通过提取URL地址中的文件名,可以直接获取图片的实际路径。
请求头设置:在请求图片资源时,需要设置合适的请求头参数,避免被百度的防爬机制拦截。
图片扩展名处理:注意到部分图片的URL地址中并没有图片的扩展名,需要根据实际情况进行补充。
以下是一个完整的Python示例,展示了如何实现百度图片的批量爬取:
import requestsimport reimport osdef batch_crawl_baidu_images(word, save_dir='images'): # 模拟浏览器请求头 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36', # 模拟无限滚动,实现分页效果 'X-Flip': '0' } # 初始化计数器 page = 0 while True: # 构建请求URL url = f'https://image.baidu.com/search/flip?word={word}&pn={page}' response = requests.get(url, headers=headers) response.encoding = 'utf-8' text = response.text # 提取当前页面的图片URL地址 picture_urls = re.findall(r'"objURL":"(.*?)"', text) if not picture_urls: break # 如果没有找到图片URL,停止循环 # 下载并保存图片 for url in picture_urls: # 提取图片文件名 filename = url.split('/')[-1] file_ext = filename.split('.')[-1] # 如果扩展名缺失,补充 if file_ext not in ['png', 'jpg', 'jpeg', 'gif']: filename += '.' + file_ext filepath = os.path.join(save_dir, filename) try: response_img = requests.get(url, headers=headers, timeout=5) with open(filepath, 'wb') as f: f.write(response_img.content) except Exception as e: print(f'下载图片失败:{e}') page += 1 # 跳到下一页 print(f'完成爬取,共下载了{len(os.listdir(save_dir))}张图片')# 示例使用:爬取关键词“自然风光”batch_crawl_baidu_images('自然风光', '自然风光') 在实际应用中,需要注意以下几点:
防爬机制:部分网站会对爬虫行为进行限制,建议在爬取过程中设置合理的爬取间隔,避免触发反爬机制。
网页格式变化:由于瀑布流和分页模式的存在,网页的结构可能会有所变化,需要动态调整提取规则。
图片质量控制:在爬取过程中,可以通过设置合理的参数(如不下载过小图片),来筛选图片质量。
多线程下载:为了提高爬取效率,可以在下载过程中采用多线程方式,同时处理多个图片请求。
通过以上方法,可以轻松实现对百度图片的批量爬取需求。
转载地址:http://krun.baihongyu.com/