Python中的html.parser

本文介绍了一个简单的HTML网页解析器类的实现,通过继承HTMLParser并重写相关方法,可以提取网页中的链接及其描述数据。

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

class WebPageParser(html.parser.HTMLParser):
    def __init__(self, strict = False):
        super().__init__(strict)
        self.urls = []
        self.data = []
        self.is_href = False;
    def handle_starttag(self, tag, attrs):
        if tag == 'a':
            self.urls.extend([v for k , v in attrs if k == 'href'])
            self.is_href = True
    def handle_endtag(self, tag):
        print(tag)
        self.is_href = False
    def handle_startendtag(self, tag, attrs):
        print(tag, attrs)
    def handle_data(self, data):
        if self.is_href:
            self.data.append(data)
            
    def reset(self):
        super().reset()
        self.urls = []
        self.data = []
        self.is_href = False
        
if __name__ == '__main__':
    webUrl = r"http://www.baidu.com"
    webPage = urllib.request.urlopen(webUrl)
    webPageParser = WebPageParser()
    webPageParser.feed(str(webPage.read()))
    print(webPageParser.urls)
    print(webPageParser.data)


该类的使用很简单,主要是要继承html.parser.HTMLParser,然后重载相对应的方法。

<think>嗯,用户想用Pythonhtml.parser来爬取豆瓣Top250的电影数据。首先,我需要回忆一下html.parser的基本用法,以及如何结合requests库来发送HTTP请求。 用户可能已经知道requests库,但需要确认是否需要设置请求头来避免反爬虫机制。根据提供的引用内容,比如引用[2]和[3],都提到了设置User-Agent来模拟浏览器访问。所以第一步应该是构造请求头,使用requests.get发送请求,获取网页内容。 接下来是解析HTML。用户指定使用html.parser,而不是BeautifulSoup或者其他解析库。所以需要导入HTMLParser并创建一个子类,重写处理标签的方法。比如,当遇到<div class="item">这样的标签时,可能表示一个电影条目,这时候需要开始提取数据。 在解析过程中,需要定位电影名称、评分等信息的位置。比如,电影名称可能在<span class="title">里,评分在<span class="rating_num">里。需要处理标签的开始和结束,以及数据内容的捕获。例如,当进入一个电影标题的标签时,设置一个标志位,然后在处理数据时保存内容。 分页处理也是关键,豆瓣Top250有多个页面,每页25条,共10页。需要构造不同的URL,例如https://movie.douban.com/top250?start=0,start=25,直到start=225。循环发送请求,解析每一页的内容。 另外,需要注意异常处理,比如请求失败时重试,或者添加延时防止被封IP。但用户的问题可能更关注基础实现,所以可能先不涉及复杂处理,但应该提到这些优化点。 最后,保存数据可以用CSV或者列表存储,用户可能需要将结果打印出来或者保存到文件里。同时,需要测试代码是否正常工作,比如打印出电影名称和评分,检查是否有遗漏或错误。 用户提供的引用中,其他爬虫示例用了BeautifulSoup,但这里需要转换到html.parser,所以需要比较两者的差异,确保解析逻辑正确。可能需要处理嵌套标签,比如电影名称可能在多个span中,需要正确提取第一个中文标题,忽略其他语言的标题。 总结步骤:发送请求获取页面,解析HTML结构提取所需数据,处理分页,存储结果。过程中需要注意反爬措施和代码的健壮性。</think>以下是使用Python标准库`html.parser`实现豆瓣Top250电影数据爬取的完整步骤: ### 一、实现流程 1. **HTTP请求配置** - 设置`User-Agent`请求头规避反爬检测(参考引用[2][^2]) - 使用`requests`发送带请求头的GET请求 ```python import requests headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' } ``` 2. **HTML解析器定义** ```python from html.parser import HTMLParser class DoubanParser(HTMLParser): def __init__(self): super().__init__() self.movies = [] self.current_tag = None self.current_movie = {} def handle_starttag(self, tag, attrs): attrs = dict(attrs) if tag == 'div' and attrs.get('class') == 'item': self.current_movie = {} elif tag == 'span' and attrs.get('class') == 'title': self.current_tag = 'title' elif tag == 'span' and attrs.get('class') == 'rating_num': self.current_tag = 'rating' def handle_data(self, data): if self.current_tag == 'title' and not data.strip().startswith('/'): self.current_movie['title'] = data.strip() elif self.current_tag == 'rating': self.current_movie['rating'] = data.strip() self.current_tag = None def handle_endtag(self, tag): if tag == 'div' and self.current_movie: self.movies.append(self.current_movie) ``` 3. **分页处理逻辑** ```python base_url = "https://movie.douban.com/top250?start={}" for page in range(0, 250, 25): response = requests.get(base_url.format(page), headers=headers) parser = DoubanParser() parser.feed(response.text) ``` ### 二、完整代码实现 ```python import requests from html.parser import HTMLParser class MovieParser(HTMLParser): def __init__(self): super().__init__() self.in_item = False self.current_movie = {} self.movies = [] self.current_tag = None def handle_starttag(self, tag, attrs): attrs = dict(attrs) if tag == 'div' and attrs.get('class') == 'item': self.in_item = True self.current_movie = {} elif self.in_item: if tag == 'span' and attrs.get('class') == 'title': self.current_tag = 'title' elif tag == 'span' and attrs.get('class') == 'rating_num': self.current_tag = 'rating' def handle_data(self, data): if self.current_tag == 'title' and not data.strip().startswith('/'): self.current_movie['title'] = data.strip() elif self.current_tag == 'rating': self.current_movie['rating'] = data.strip() self.current_tag = None def handle_endtag(self, tag): if tag == 'div' and self.in_item: self.in_item = False if self.current_movie: self.movies.append(self.current_movie) headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'} all_movies = [] for start in range(0, 250, 25): url = f'https://movie.douban.com/top250?start={start}' response = requests.get(url, headers=headers) parser = MovieParser() parser.feed(response.text) all_movies.extend(parser.movies) for idx, movie in enumerate(all_movies[:25], 1): print(f"{idx}. {movie['title']} 评分:{movie.get('rating', '暂无')}") ``` ### 三、技术要点说明 1. **反爬规避**:必须设置有效的`User-Agent`请求头(参考引用[3][^3]) 2. **标签状态管理**:通过`in_item`标记跟踪电影条目边界 3. **数据清洗**:过滤标题中的斜杠符号(处理多语言标题) 4. **错误处理建议**:可添加`try-except`块处理网络异常,建议添加`time.sleep(2)`降低请求频率
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值