python怎么爬取网站图片
用Python爬图片,网站核心就三行代码的图片事:发请求、解析HTML、网站下载二进制。图片但真跑起来,网站坑比想象的图片多。我上周想爬一个壁纸站,网站结果发现对方把图片链接藏在JavaScript里,图片requests拿到的网站HTML里根本没有img标签。这就是图片第一个现实问题——静态页面和动态渲染的区别。 先看最基础的网站场景。假设目标网站是图片传统服务端渲染,图片直接写在HTML的网站img src里。你需要两个库:requests负责网络请求,图片BeautifulSoup负责解析。网站安装就不说了,pip一行的事。 这段代码能跑通的前提是网站没做反爬。实际上,很多站点会检查Referer、User-Agent,甚至用Cloudflare挡在前面。我试过一个摄影论坛,不加headers直接返回403,加上浏览器UA后正常。所以headers不是可选项,是必需品。 拿到图片URL后,下载逻辑很简单。但要注意,图片是二进制数据,不能用resp.text,得用resp.content。另外,文件名最好从URL里提取,或者用哈希值避免重名。 这里有个细节:有些图片URL带查询参数,比如 动态页面怎么办?比如用Vue或React做的图库,图片是滚动加载的。这时候requests拿到的HTML里只有空壳。方案有两个:一是找XHR接口,打开开发者工具的Network面板,筛选XHR,看图片数据是不是通过JSON返回的;二是用Selenium或Playwright模拟浏览器,等页面渲染完再提取。 我倾向于优先找接口。上周那个壁纸站,翻页时请求了一个 Selenium的方案更通用,代价是慢。启动Chrome、加载页面、等待元素出现,每一步都可能超时。代码大概长这样: 反爬是绕不开的话题。除了headers,还有几个常见手段:限制请求频率、封IP、图片URL带时效签名。我一般会在下载循环里加 最后说个容易被忽略的点:版权。爬图片自己看看没问题,批量下载再传播,尤其是商业用途,法律风险是实打实的。我见过有人爬了图库网站拿去卖,结果收到律师函。技术归技术,用的时候心里得有根弦。 整个流程跑通后,你会发现最耗时的不是写代码,而是分析目标网站的结构。每个站都不一样,有的把原图放在import requests from bs4 import BeautifulSoup from urllib.parse import urljoin url = "https://example.com/gallery" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"} resp = requests.get(url, headers=headers) soup = BeautifulSoup(resp.text, "html.parser") for img in soup.find_all("img"): src = img.get("src") if src: full_url = urljoin(url, src) print(full_url) import os, hashlib def download_img(img_url, save_dir="images"): os.makedirs(save_dir, exist_ok=True) try: r = requests.get(img_url, headers=headers, timeout=10) if r.status_code == 200: ext = img_url.split(".")[-1].split("?")[0] name = hashlib.md5(img_url.encode()).hexdigest()[:12] + "." + ext path = os.path.join(save_dir, name) with open(path, "wb") as f: f.write(r.content) print("saved:", path) except Exception as e: print("failed:", img_url, e) photo.jpg?w=800,直接按点分割扩展名会出错。得先去掉问号后面的部分。我踩过这个坑,下载下来一堆没有后缀的文件。/api/wallpapers?page=2的接口,返回JSON里直接有原图链接。这比模拟浏览器快十倍,还省资源。但接口可能有签名或token,得看具体实现。from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Chrome() driver.get(url) WebDriverWait(driver, 10).until( EC.presence_of_all_elements_located((By.TAG_NAME, "img")) ) imgs = driver.find_elements(By.TAG_NAME, "img") for img in imgs: src = img.get_attribute("src") # 下载逻辑同上 driver.quit() time.sleep(0.5),别小看这半秒,能避免触发频率限制。如果IP被封,就得用代理池,但个人小规模爬取没必要搞那么复杂。data-src里做懒加载,有的用srcset响应式图片,还有的把图片转成base64嵌在CSS背景里。遇到这些,就得具体问题具体拆。工具是死的,思路是活的。
-
上一篇
-
下一篇
- 最近发表
- 随机阅读
- 搜索
-
- 友情链接
-