Python爬虫之静态页面爬取

本文介绍如何使用Python编写爬虫程序抓取指定网站上的图片资源,包括需求分析、框架选择及具体实现步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Python爬虫之静态页面爬取

前言

Python语言代码简短,功能精悍。如Python之父所言 “人生苦短,我用Python” 。所以Python语言写爬虫具有其他语言比不了的优势。Python简直为爬虫而生。

在写爬虫程序之前,先说下爬虫程序的步骤,爬虫程序一般分为以下几步:

  • 1. 明确爬虫需求

    • 1.1 需求分析
  • 2. 选择爬虫框架

    • 2.1 框架简介
  • 3. 编写爬虫程序

    • 3.1 抓取网页数据

    • 3.2 清洗网页数据(通过规则获取网页数据)

    • 3.3 保存数据


1. 明确爬虫需求

本文需要爬取的网站是:http://www.jandan.net/ooxx

需要爬取的内容是:爬取该网站的美女图片。

1.1 需求分析

首先我们打开需要爬取的网站,选中一张美女图片,点击鼠标右键,选中检查,查看这张图片在html页面的位置。打开浏览器xpath-helper插件(没安装该插件可以通过浏览器应用安装),如下图所示:

image

通过使用xpath语法进行规则匹配,查找到我们想要的资源图片。同时我们也需要爬取下一页的图片数据,通过xpath语法找到下一页的url,加载下一页数据。所以我们需要采用递归的方式一页一页的爬取图片数据。


2. 爬虫框架的选择

本文采用Python3.6版本开发环境。

网络请求框架使用:urllib

html页面解析框架使用:lxmlxpath语法

最后将爬取的数据保存到本地文件。

2.1 框架简介
  • urllib 框架

    urllibPython3.0的一个http网络请求框架,是系统的框架,功能比较强大。

    urllib类库包含四个模块:request模块,parse模块,error模块,robotparser模块。

    我们一般常用的是urllib.request模块。下面介绍一下request模块的常用api:

    • urlopen():请求url的方法,参数比较多,如下:
    urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
            *, cafile=None, capath=None, cadefault=False, context=None)
    
    1. url:可以是一个string或者是一个Request对象。(重点)
    
    2. data:默认是None。(重点)
        如果传参需要传入dict字典类型。提供数据参数时,HTTP请求将是POST而不是GET
        data应该使用application / x-www-form-urlencoded格式,需要urllib.parse.urlencode()进行编码。
    
    3. timeout:超时时间
    
    4. cafile:cafile应指向包含一系列CA证书的单个文件
    
    5. capath:capath应指向散列证书文件的目录
    
    6. cadefault:参数是否被忽略
    
    7. context:如果指定了上下文,则它必须是描述各种SSL选项的ssl.SSLContext实例。
    
    
    urlopen()返回的一个上下文的管理对象,对于http,https,返回的是一个http.client.HTTPResponse对象。
    
    • HTTPResponse对象
    HTTPResponse对象,将响应的数据封装起来,常用的方法有:
    
    response.geturl():返回检索资源的URL,通常用于确定是否遵循重定向
    
    response.code():返回的是响应码
    
    response.msg:返回的是响应信息
    
    response.info():返回的是响应头信息
    
    response.read():读取响应的数据,响应体
    

    详细API可看下面官方文档:

    urllib官网文档

    HTTPResponse官网文档

  • lxml类库和xpath语法

    lxml类库是一个Html/XML的解析器,主要功能是如何解析和提取HTML/XML数据。

    • lxml的安装
    pip install lxml
    • lxml的api介绍

    lmxl借助etree模块,来处理xml和html的数据。如下所示:

    
    # 1. 将html页面数据转成ElementTree对象
    
    tree = etree.HTML(text) 
    
    
    # 2. 解析一个html文件,返回一个ElementTree对象
    
    tree = etree.parse('xxxx.html')
    
    
    # 3. 通过xpath语法解析规则,解析ElementTree对象
    
    
    #    参数rule是xpath解析html的规则(具体参考xpath语法文档)。
    
    
    #    返回一个结果集(结果集有可能是Element的list集合,也有可能是字符串的list结合)
    
    results = tree.xpath(rule)
    
    
    # 4. 将Element/ElementTree对象转成html的文本信息,返回一个文本信息
    
    etree.tostring(element)
    
    
    # 5. 获取Element对象(html标签)的文本信息
    
    str = element.text
    

    文档参考:

    lxml官方文档

    xpath语法文档


3. 编写爬虫程序

我们明确需求,选择好框架后,就开始编写爬虫程序了,我们将爬虫程序分为3步,抓取数据,清洗数据,保存数据。
为了代码能很好的复用,我们把它封装成一个类JanDanSpider。定义3个方法,load_page() , parse_page() , load_image(), 如下:

class JanDanSpider(object):

    def __init__(self):
        pass

    def load_page(self):
        pass

    def parse_page(self):
        pass

    def load_image(self):
        pass
3.1 抓取网页数据

通过urllib.request模块,请求url链接,返回响应的内容。因为我们需要递归解析页面,以及加载图片,所有将请求的方法提取出来,封装成一个get_response()方法,具体如下:

import urllib.request

class JanDanSpider(object):

    def __init__(self):
        pass

    def get_response(self , url):

        # 修改http的headers的User-Agent头字段,如果不修改,默认是Python-urllib/3.6
        # 如果使用默认的User-Agent,这样就直接暴露这是一个爬虫程序,就容易导致ip被封。
        headers = {
            "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36"
        }

        # 通过Request获取一个请求对象request
        request = urllib.request.Request(url, headers = headres)

        # 发送请求,返回一个响应对象response 
        response = urllib.request.urlopen(request)

        # 将服务端返回的数据返回出去
        return response.read()


    def load_page(self , url):
        # 1. 调用get_response方法,获取网页数据
        response  = self.get_response(url)

        # 2. ... 下面继续

    def parse_page(self):
        pass

    def save_image(self):
        pass
3.2 清洗网页数据

当我们获取网页返回的响应数据,接下来就是使用lxmlxpath规则解析网页的数据。

在”http://www.jandan.net/ooxx“网页中,有2种图片,一种是正常显示出来的normal图片,一种是大图,需要点击查看大图才能看到。除此之外,我们还需要解析出上一页的页面的url。

因为解析的方法都是一致的,只是rule的规则不同,返回的数据不同,所以我们将复用解析方法。传入rule参数。

import urllib.request
from lxml import etree

class JanDanSpider(object):

    def __init__(self):

        # 大图的xpath解析规则
        self.rule_large = "//ol[@class='commentlist']/li//a[@class='view_img_link']/@href"
        # 正常图的xpath解析规则
        self.rule_normal = "//ol[@class='commentlist']/li//img/@src"
        # 上一页的xpath解析规则
        self.rule_pre_page = "//div[@class='comments']//a[@class='previous-comment-page']/@href"


    def load_page(self , url):

        # 获取服务端的响应数据
        text = self.get_response(url)

        # 通过大图的解析规则,处理大图的结果集
        self.deal_images(self.parse_page(text, self.rule_large))
        # 通过正常图的解析规则,处理正常图的结果集
        self.deal_images(self.parse_page(text, self.rule_normal))
        # 通过上一页的解析规则,处理上一页的结果集
        self.deal_pre_page(self.parse_page(text, self.rule_pre_page))


    def parse_page(self, text, rule):
        """
        解析页面
        :param text: 服务端返回的数据
        :param rule: 解析规则
        :return: 返回解析页面的结果
        """
        # 通过etree库,将服务端返回的页面数据封装成ElementTree对象
        tree = etree.HTML(text)
        # 通过xpath规则(rule)解析ElementTree对象,返回数据列表
        return tree.xpath(rule)


    def deal_images(self, images):
        """
        处理页面解析获得的图片
        :param images: 解析页面返回的图片集合
        :return:
        """
        if images is not None:
            # 遍历数据列表
            for image in images:
                if 'http:' not in image:
                    # 拼接图片的url
                    image = 'http:' + image
                print(image)
                # 下载图片
                self.load_image(image)


    def deal_pre_page(self, results):
        """
        处理下一页
        :param results: 解析页面结果
        :return:
        """
        if results is not None:
            # 因为在页面有2处,解析有2个一样的地址
            if len(results) > 0:
                # 取第一个
                url = results[0]
                if self.host in url:
                    if 'http:' not in url:
                        # 拼接字符串
                        url = 'http:' + url
                        # 加载下一个页面
                        self.load_page(url)


    def load_image(self, image_url):
        pass
3.3 保存数据

最后获取的数据,是图片的url链接,我们需要将url链接下载对应的图片,并保存到本地。

class JanDanSpider(object):

    def load_image(self, image_url):
        """
        下载图片
        :param image_url: 图片的url
        :return:
        """
        with open(self.create_filename(image_url), 'wb')as f:
            f.write(self.get_response(image_url))


    def create_filename(self, image_url):
        """
        通过图片的url来确定存储路径
        :param image_url:   图片的url
        :return:
        """
        results = image_url.split('/')
        if 'large' in image_url:
            filename = 'image/large/' + results[-1]
        else:
            filename = 'image/normal/' + results[-1]
        return filename

最后我们调用爬虫程序,然后运行:

if __name__ == 'main':
    # 爬取的网站
    url = "http://jandan.net/ooxx"
    spider = JanDanSpider()
    spider.load_page(url)

运行输出的图片url,如图:

image

具体代码,可参见我的github , GitHub项目地址

<think>嗯,用户想复习Python爬虫静态页面抓取方法,需要提供一个教程。首先,我得回忆一下静态页面抓取的基本步骤和相关库。记得常用的库有urllib和requests,这两个都是Python自带的或者第三方常用的。用户可能已经有一些基础,但需要系统性的复习,所以结构要清晰。 首先,应该分步骤讲解,从发送HTTP请求开始。然后处理请求头,设置超时和重试,处理响应内容,比如状态码和编码,最后解析内容,比如用BeautifulSoup。还要注意代码示例的正确性,确保用户能复制运行。 用户提供的引用里提到了urllib.request和requests库的使用,还有状态码、编码这些关键点。需要把这些内容整合到教程中,同时保持逻辑连贯。可能还需要比较不同库的优缺点,比如urllib是标准库,而requests更简洁。 另外,用户可能对实际操作中的常见问题感兴趣,比如处理异常、设置请求头防止被屏蔽,或者解析HTML时的选择器使用。需要覆盖这些点,但不要过于深入,保持教程的复习性质。 还要注意引用标记,每个引用来源在适当的地方标注。比如,讲解请求过程时引用[^1],urllib的例子引用[^2],requests的例子引用[^3]。确保引用自然,不打断内容流畅性。 可能还需要提醒用户注意法律和道德规范,比如遵守robots.txt,不过用户的问题主要是技术方法,这部分可以放在注意事项里简要提及。 最后生成相关问题,帮助用户进一步学习。问题要围绕静态页面抓取的扩展知识,比如动态页面对比、反爬策略、数据处理等。这样用户可以根据问题继续深入学习。 检查一下是否有遗漏的关键点,比如处理GET和POST请求,或者保存抓取的数据。不过静态页面抓取主要是GET,所以可能不需要涉及POST。保存数据可以作为扩展,但用户需求是复习基本方法,所以可能不需要深入。 确保代码示例正确,比如urllib的import和requests的使用,特别是decode和.text的区别。还有状态码检查,200表示成功,这些要提到。 总结下来,结构应该是: 1. 概述静态页面抓取 2. 使用urllib库的步骤和示例 3. 使用requests库的步骤和示例 4. 解析HTML(BeautifulSoup) 5. 注意事项 6. 相关问题 每个部分配合引用和代码示例,确保用户能一步步回顾知识点。需要语言简洁,步骤明确,避免复杂术语,但保持专业性。</think>### Python静态页面抓取方法教程 #### 一、静态页面抓取原理 静态网页内容直接存储在服务器中,通过HTTP请求可直接获取HTML源码。爬虫的核心步骤包括**发送请求**、**获取响应**、**解析内容**三部分。 --- #### 二、使用urllib库实现 Python内置的`urllib`是基础HTTP请求库,适合简单场景: ```python import urllib.request # 发送请求 response = urllib.request.urlopen('http://www.example.com') # [^2] # 读取内容(需指定编码) html = response.read().decode('UTF-8') print(html) ``` **关键参数:** - `timeout=10`:设置超时时间 - `headers={}`:添加请求头模拟浏览器 --- #### 三、使用requests库实现(推荐) 第三方库`requests`提供更简洁的API: ```python import requests # 带请求头的GET请求 headers = {'User-Agent': 'Mozilla/5.0'} response = requests.get('https://blog.example.com', headers=headers) # [^3] # 检查状态码 if response.status_code == 200: print("编码方式:", response.encoding) print("网页内容:", response.text) ``` --- #### 四、HTML解析方法 使用`BeautifulSoup`解析获取的内容: ```python from bs4 import BeautifulSoup soup = BeautifulSoup(response.text, 'html.parser') title = soup.find('h1').text # 提取标题 links = [a['href'] for a in soup.find_all('a')] # 提取所有链接 ``` --- #### 五、注意事项 1. **请求频率控制**:添加`time.sleep(2)`避免被封禁 2. **异常处理**:使用`try-except`捕获`ConnectionError` 3. **编码检测**:优先使用`response.apparent_encoding`自动检测编码 4. **遵守robots协议**:检查`/robots.txt`文件 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值