BS4快速入门:解析HTML与XML的利器

需积分: 9 1 下载量 168 浏览量 更新于2024-08-10 收藏 96KB DOCX 举报
"这是一份关于BS4(BeautifulSoup)的快速上手入门手册,主要讲解了如何安装和使用BeautifulSoup进行网页数据的提取。它是一个用于解析HTML和XML文件的Python库,提供了方便的数据解析功能。此外,还介绍了安装lxml解析器的步骤以及BeautifulSoup、Tag、NavigableString和Comment四大对象的使用方法。手册还重点阐述了遍历文档树和搜索文档树的两大方法,包括父节点、子节点、兄弟节点的遍历以及find、find_all、select_one和select等搜索方法。" 在Python的网络爬虫领域,BeautifulSoup是一个非常重要的工具,它能够帮助开发者高效地解析HTML和XML文档,提取所需的数据。以下是对标题和描述中涉及知识点的详细说明: 1. **安装BeautifulSoup** - 安装BeautifulSoup库的命令是`pip install beautifulsoup4`,这将使你能够在Python环境中使用BeautifulSoup的功能。 2. **解析器** - 解析器是用于处理HTML或XML文档的组件,这里推荐使用lxml解析器,通过`pip install lxml`进行安装。 - 使用BeautifulSoup时,需要传入解析器,如`soup = BeautifulSoup(open("index.html"), 'lxml')`或`soup = BeautifulSoup("<html>data</html>", 'lxml')`。 3. **四大对象** - **BeautifulSoup对象**:代表整个文档,可以像处理Tag对象一样进行操作,支持遍历和搜索文档树。 - **Tag对象**:对应HTML或XML文档中的标签,可以通过`.name`获取标签名,`.get('class')`获取class属性。 - **NavigableString对象**:表示标签内的文本,可以通过`.string`访问。 - **Comment对象**:用于处理文档中的注释,可以通过`.string`获取注释内容。 4. **遍历文档树** - **父节点和父母**:使用`.parent`获取父节点,`.parents`遍历所有父节点。 - **子节点**:`.contents`返回子节点列表,`.children`迭代子节点。 - **兄弟节点**:`.next_sibling`获取下一个兄弟节点,`.previous_sibling`获取上一个兄弟节点,`.next_siblings`和`.previous_siblings`遍历所有兄弟节点。 5. **搜索文档树** - **find方法**:根据指定条件查找第一个匹配的元素。 - **find_all方法**:查找所有匹配的元素,返回列表。 - **select_one方法**:CSS选择器查找第一个匹配的元素。 - **select方法**:CSS选择器查找所有匹配的元素,返回列表。 了解并掌握这些知识点,你就能基本掌握使用BS4进行网页解析的基础操作。通过遍历和搜索文档树,你可以有效地提取网页中的特定信息,这对于网络爬虫的开发至关重要。在实际项目中,结合requests库获取网页内容,然后利用BeautifulSoup解析,可以实现高效的数据抓取。

原始代码:import requests from bs4 import BeautifulSoup import pandas as pd import re import matplotlib.pyplot as plt import seaborn as sns from matplotlib import font_manager from docx import Document from docx.shared import Inches import os def get_movie_data(): headers = {"User-Agent": "Mozilla/5.0"} movie_list = [] for start in range(0, 300, 25): url = f"https://movie.douban.com/top250?start={start}" response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') items = soup.find_all('div', class_='item') for item in items: title = item.find('span', class_='title').text.strip() info = item.find('p').text.strip() director_match = re.search(r'导演: (.*?) ', info) director = director_match.group(1) if director_match else 'N/A' details = info.split('\n')[1].strip().split('/') year = details[0].strip() if len(details) > 0 else 'N/A' country = details[1].strip() if len(details) > 1 else 'N/A' genre = details[2].strip() if len(details) > 2 else 'N/A' rating = item.find('span', class_='rating_num').text if item.find('span', class_='rating_num') else 'N/A' num_reviews = item.find('div', class_='star').find_all('span')[-1].text.strip('人评价') if item.find('div', class_='star').find_all('span') else 'N/A' movie_list.append({ 'title': title, 'director': director, 'year': year, 'country': country, 'genre': genre, 'rating': rating, 'num_reviews': num_reviews }) return pd.DataFrame(movie_list) # 定义输出目录 output_dir = 'D:/0610' os.makedirs(output_dir, exist_ok=True) # 获取电影数据并保存到CSV df = get_movie_data() csv_path = os.path.join(output_dir, 'top300_movies.csv') df.to_csv(csv_path, index=False) print(f'Data saved to {csv_path}') # 设置中文字体 plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False # 读取数据 df = pd.read_csv(csv_path) # 任务 1: 分析最受欢迎的电影类型,导演和国家 top_genres = df['genre'].value_counts().head(10) top_directors = df['director'].value_counts().head(10) top_countries = df['country'].value_counts().head(5) # 任务 2: 分析上映年份的分布及评分与其他因素的关系 df['year'] = pd.to_numeric(df['year'].str.extract(r'(\d{4})')[0], errors='coerce') year_distribution = df['year'].value_counts().sort_index() rating_reviews_corr = df[['rating', 'num_reviews']].astype(float).corr() # 可视化并保存图表 def save_plot(fig, filename): path = os.path.join(output_dir, filename) fig.savefig(path) plt.close(fig) return path fig = plt.figure(figsize=(12, 8)) sns.barplot(x=top_genres.index, y=top_genres.values) plt.title('最受欢迎的电影类型') plt.xlabel('电影类型') plt.ylabel('数量') plt.xticks(rotation=45) top_genres_path = save_plot(fig, 'top_genres.png') fig = plt.figure(figsize=(12, 8)) sns.barplot(x=top_directors.index, y=top_directors.values) plt.title('出现次数最多的导演前10名') plt.xlabel('导演') plt.ylabel('数量') plt.xticks(rotation=45) top_directors_path = save_plot(fig, 'top_directors.png') fig = plt.figure(figsize=(12, 8)) sns.barplot(x=top_countries.index, y=top_countries.values) plt.title('出现次数最多的国家前5名') plt.xlabel('国家') plt.ylabel('数量') plt.xticks(rotation=45) top_countries_path = save_plot(fig, 'top_countries.png') fig = plt.figure(figsize=(12, 8)) sns.lineplot(x=year_distribution.index, y=year_distribution.values) plt.title('电影上映年份分布') plt.xlabel('年份') plt.ylabel('数量') plt.xticks(rotation=45) year_distribution_path = save_plot(fig, 'year_distribution.png') fig = plt.figure(figsize=(12, 8)) sns.heatmap(rating_reviews_corr, annot=True, cmap='coolwarm', xticklabels=['评分', '评论人数'], yticklabels=['评分', '评论人数']) plt.title('评分与评论人数的相关性') rating_reviews_corr_path = save_plot(fig, 'rating_reviews_corr.png')

2025-03-08 上传