python利用html.parser爬取豆瓣top250
时间: 2025-06-12 22:07:02 浏览: 13
<think>嗯,用户想用Python的html.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)`降低请求频率
阅读全文
相关推荐
















