Python:如何爬取网页中图片的技术指南

1、简述

在互联网时代,数据无处不在。网页上的图片不仅丰富了内容,还蕴含了大量有价值的信息。无论是用于数据分析、机器学习训练,还是构建自己的图片库,爬取网页中的图片都是一个常见且实用的需求。本文将深入探讨如何使用 Python 编写爬虫来爬取网页中的图片,并提供详细的实现过程和代码示例。

2、爬虫工具

网页爬虫(Web Crawler)是一种自动化程序,用于系统地浏览互联网,抓取网页内容并提取有用的信息。爬虫广泛应用于搜索引擎索引、数据分析、内容聚合等领域。

在 Python 中,有多种库和工具可以用来编写爬虫,以下是一些常用的工具:

  • Requests
    requests 是一个简单易用的 HTTP 客户端库,用于发送 HTTP 请求,获取网页内容。
  • pip install requests
    
  • BeautifulSoup
    BeautifulSoup 是一个用于解析 HTML 和 XML 文档的库,能够轻松提取网页中的特定内容。
  • pip install beautifulsoup4
    
  • Selenium
    Selenium 是一个自动化测试工具,可以驱动浏览器进行交互,适用于处理动态加载内容的网页。
  • pip install selenium
    

    注意: 使用 Selenium 需要下载对应浏览器的 WebDriver,例如 ChromeDriver。

    3、爬取流程

  • 发送HTTP请求:获取目标网页的HTML内容。
  • 解析网页内容:使用解析库(如 BeautifulSoup)解析HTML。
  • 提取图片URL:找到网页中所有的图片标签,获取图片的URL。
  • 下载并保存图片:根据提取的URL下载图片并保存到本地。
  • 3.1 环境准备

    确保已经安装了必要的库:

    pip install requests beautifulsoup4
    
    3.2 发送HTTP请求

    使用 requests 发送GET请求,获取网页内容:

    import requests
    
    url = 'https://example.com'
    response = requests.get(url)
    
    if response.status_code == 200:
        html_content = response.text
    else:
        print(f'Failed to retrieve content: {response.status_code}')
    
    3.3 解析网页内容

    使用 BeautifulSoup 解析HTML内容,提取图片标签:

    from bs4 import BeautifulSoup
    
    soup = BeautifulSoup(html_content, 'html.parser')
    img_tags = soup.find_all('img')
    
    3.4 提取图片URL

    从图片标签中提取 src 属性,获取图片的URL:

    import os
    from urllib.parse import urljoin
    
    image_urls = []
    for img in img_tags:
        img_url = img.get('src')
        # 处理相对URL
        img_url = urljoin(url, img_url)
        image_urls.append(img_url)
    
    3.5 下载并保存图片

    遍历提取到的图片URL,下载并保存到本地目录:

    import requests
    
    # 创建保存图片的文件夹
    save_folder = 'downloaded_images'
    os.makedirs(save_folder, exist_ok=True)
    
    for img_url in image_urls:
        try:
            img_response = requests.get(img_url, stream=True)
            if img_response.status_code == 200:
                # 提取图片名
                img_name = os.path.basename(img_url)
                img_path = os.path.join(save_folder, img_name)
                # 保存图片
                with open(img_path, 'wb') as f:
                    for chunk in img_response.iter_content(1024):
                        f.write(chunk)
                print(f'Downloaded: {img_url}')
            else:
                print(f'Failed to download {img_url}: {img_response.status_code}')
        except Exception as e:
            print(f'Error downloading {img_url}: {e}')
    
    3.6 完整代码示例

    以下是一个完整的 Python 脚本,演示如何爬取网页中的所有图片并保存到本地:

    import requests
    from bs4 import BeautifulSoup
    import os
    from urllib.parse import urljoin
    
    def is_valid(url):
        # 检查URL是否有效
        return url.startswith('http') or url.startswith('https')
    
    def get_all_images(url):
        response = requests.get(url)
        if response.status_code != 200:
            print(f'Failed to retrieve content from {url}')
            return []
        
        soup = BeautifulSoup(response.text, 'html.parser')
        img_tags = soup.find_all('img')
        
        image_urls = []
        for img in img_tags:
            img_url = img.get('src')
            if not img_url:
                continue
            img_url = urljoin(url, img_url)
            if is_valid(img_url):
                image_urls.append(img_url)
        return image_urls
    
    def download_image(url, folder):
        try:
            response = requests.get(url, stream=True)
            if response.status_code == 200:
                img_name = os.path.basename(url.split('?')[0])  # 处理带参数的URL
                img_path = os.path.join(folder, img_name)
                with open(img_path, 'wb') as f:
                    for chunk in response.iter_content(1024):
                        f.write(chunk)
                print(f'Downloaded: {url}')
            else:
                print(f'Failed to download {url}: {response.status_code}')
        except Exception as e:
            print(f'Error downloading {url}: {e}')
    
    def main():
        url = 'https://example.com'  # 替换为目标网页
        save_folder = 'downloaded_images'
        os.makedirs(save_folder, exist_ok=True)
        
        print(f'Fetching images from {url}...')
        images = get_all_images(url)
        print(f'Found {len(images)} images.')
        
        for img_url in images:
            download_image(img_url, save_folder)
    
    if __name__ == '__main__':
        main()
    

    使用说明:

  • 将 https://example.com 替换为你想要爬取的目标网页。
  • 运行脚本后,图片将被下载到当前目录下的 downloaded_images 文件夹中。
  • 4、高级技巧运用

    4.1 处理动态加载的内容

    有些网站的图片是通过 JavaScript 动态加载的,使用 requests 和 BeautifulSoup 无法直接获取到这些图片。此时,可以使用 Selenium 驱动浏览器,等待页面完全加载后再提取图片。

    安装 Selenium 和 WebDriver:

    pip install selenium
    

    示例代码:

    from selenium import webdriver
    from selenium.webdriver.chrome.service import Service
    from selenium.webdriver.common.by import By
    import time
    
    def get_images_with_selenium(url):
        # 设置 WebDriver 路径
        service = Service('/path/to/chromedriver')  # 替换为你的chromedriver路径
        options = webdriver.ChromeOptions()
        options.add_argument('--headless')  # 无头模式
        driver = webdriver.Chrome(service=service, options=options)
        
        driver.get(url)
        time.sleep(5)  # 等待页面加载
        
        img_elements = driver.find_elements(By.TAG_NAME, 'img')
        image_urls = [img.get_attribute('src') for img in img_elements if img.get_attribute('src')]
        
        driver.quit()
        return image_urls
    
    4.2 使用代理和头部信息

    有时目标网站会检测并阻止爬虫,导致请求失败或被封禁。可以通过设置请求头部和使用代理来规避这些限制。

    设置请求头部:

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)'
                      ' Chrome/58.0.3029.110 Safari/537.3'
    }
    
    response = requests.get(url, headers=headers)
    

    使用代理:

    proxies = {
        'http': 'http://your_proxy:port',
        'https': 'https://your_proxy:port',
    }
    
    response = requests.get(url, headers=headers, proxies=proxies)
    
    4.3 遵守网站爬虫规则

    在爬取网站时,务必遵守网站的 robots.txt 文件中的规定,尊重网站的爬虫政策,避免过于频繁的请求,防止对目标网站造成负担或引发法律问题,检查 robots.txt:

    from urllib.robotparser import RobotFileParser
    
    def can_fetch(url, user_agent='*'):
        parsed_url = requests.utils.urlparse(url)
        robots_url = f"{parsed_url.scheme}://{parsed_url.netloc}/robots.txt"
        rp = RobotFileParser()
        rp.set_url(robots_url)
        rp.read()
        return rp.can_fetch(user_agent, url)
    
    url = 'https://example.com'
    if can_fetch(url):
        # 允许爬取
        pass
    else:
        print("不允许爬取该网站。")
    
    4.4 异常处理与重试机制

    网络请求过程中可能会遇到各种异常,如连接超时、服务器错误等。可以通过添加异常处理和重试机制,提高爬虫的稳定性。

    import requests
    from requests.adapters import HTTPAdapter
    from urllib3.util.retry import Retry
    
    def create_session():
        session = requests.Session()
        retry = Retry(total=5, backoff_factor=1,
                      status_forcelist=[500, 502, 503, 504])
        adapter = HTTPAdapter(max_retries=retry)
        session.mount('http://', adapter)
        session.mount('https://', adapter)
        return session
    
    session = create_session()
    response = session.get(url, headers=headers)
    

    5、总结

    通过本文的介绍,你已经掌握了如何使用 Python 编写爬虫来爬取网页中的图片。我们从基本的请求发送、网页解析、图片URL提取到图片下载的完整流程进行了详细讲解,并提供了实际的代码示例。此外,还介绍了一些高级技巧,如处理动态加载内容、使用代理和头部信息、遵守爬虫规则等,帮助你构建更高效、稳定且合规的爬虫。

    注意事项:

  • 合法性:在爬取任何网站之前,务必确保你有权访问和使用这些数据,遵守相关法律法规和网站的使用条款。
  • 礼貌性:设置合理的请求间隔,避免对目标网站造成过大压力。
  • 数据存储:合理存储和管理爬取到的数据,避免数据泄露和滥用。
  • 通过不断实践和优化,你可以构建出功能强大、性能优越的爬虫应用,为你的项目提供有力的数据支持。
  • 希望这篇博客能帮助你更好地理解和实现图片爬取功能。如果有任何问题或建议,欢迎在评论区交流!

    作者:拾荒的小海螺

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python:如何爬取网页中图片的技术指南

    发表回复