基于Python爬虫的新闻网站爬虫及可视化的设计与实现
时间: 2023-12-02 16:03:53 浏览: 268
基于python爬虫的菜价可视化系统设计与实现.docx
5星 · 资源好评率100%
设计思路:
1. 首先确定要爬取的新闻网站,并了解该网站的网页结构和新闻分类方式。
2. 使用 Python 爬虫库 requests 和 BeautifulSoup 进行网页爬取和解析,获取新闻的标题、时间、正文、链接等信息。
3. 将获取到的新闻信息存储在本地数据库中,方便后续的数据处理和可视化。
4. 使用 Python 数据处理和可视化库 pandas、numpy、matplotlib、seaborn 等进行数据处理和可视化,分析新闻的热点话题、关键词、时间分布等信息。
5. 通过 Flask Web 框架,将分析结果可视化展示在网页上,并提供搜索和筛选功能,方便用户查找感兴趣的新闻。
实现步骤:
1. 确定要爬取的新闻网站,例如新浪新闻、腾讯新闻等。
2. 使用 requests 库获取网页的 HTML 内容,使用 BeautifulSoup 库进行解析,获取新闻的标题、时间、正文、链接等信息。
3. 使用 Python 数据库操作库 pymysql,将获取到的新闻信息存储到本地 MySQL 数据库中。
4. 使用 pandas 库进行数据处理,包括数据清洗、数据转换等操作,生成统计分析结果。
5. 使用 matplotlib、seaborn 等库进行数据可视化,生成图表展示新闻热点话题、关键词、时间分布等信息。
6. 使用 Flask Web 框架搭建 Web 服务器,将分析结果以网页的形式展示出来,并提供搜索和筛选功能。
代码实现:
1. 网页爬取和解析:
```python
import requests
from bs4 import BeautifulSoup
def get_news():
base_url = 'http://news.sina.com.cn/china/'
news_list = []
for i in range(1, 11):
url = base_url + 'index_{}.shtml'.format(i)
resp = requests.get(url)
resp.encoding = 'utf-8'
soup = BeautifulSoup(resp.text, 'html.parser')
news_items = soup.select('.news-item')
for item in news_items:
title = item.select_one('h2').text.strip()
time = item.select_one('.time').text.strip()
link = item.select_one('a')['href']
content = get_news_content(link)
news_list.append({'title': title, 'time': time, 'link': link, 'content': content})
return news_list
def get_news_content(url):
resp = requests.get(url)
resp.encoding = 'utf-8'
soup = BeautifulSoup(resp.text, 'html.parser')
content = ''
p_list = soup.select('#article p')
for p in p_list:
content += p.text.strip()
return content
```
2. 数据库存储:
```python
import pymysql
def save_news(news_list):
db = pymysql.connect(host='localhost', user='root', password='password', database='news', charset='utf8mb4')
cursor = db.cursor()
for news in news_list:
sql = "INSERT INTO news(title, time, link, content) VALUES (%s, %s, %s, %s)"
cursor.execute(sql, (news['title'], news['time'], news['link'], news['content']))
db.commit()
db.close()
```
3. 数据处理和可视化:
```python
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
def analysis_news():
db = pymysql.connect(host='localhost', user='root', password='password', database='news', charset='utf8mb4')
df = pd.read_sql('SELECT * FROM news', con=db)
df['date'] = pd.to_datetime(df['time'].str.slice(0, 10))
df['hour'] = df['time'].str.slice(11, 13).astype(int)
df['year'] = df['date'].dt.year
df['month'] = df['date'].dt.month
df['weekday'] = df['date'].dt.weekday
df['keyword'] = df['title'].str.extract('(疫情|防控|复工|复产|经济|政策|医疗|物资|援助|志愿者)')
# 热点话题
keyword_count = df['keyword'].value_counts().head(10)
plt.figure(figsize=(8, 6))
sns.barplot(x=keyword_count.values, y=keyword_count.index)
plt.title('Top 10 Keywords', fontsize=15)
plt.xlabel('Count', fontsize=12)
plt.ylabel('Keyword', fontsize=12)
plt.show()
# 时间分布
time_count = df.groupby(['year', 'month'])['title'].count().reset_index(name='count')
plt.figure(figsize=(12, 6))
sns.lineplot(x='month', y='count', hue='year', data=time_count)
plt.title('Monthly News Count', fontsize=15)
plt.xlabel('Month', fontsize=12)
plt.ylabel('Count', fontsize=12)
plt.show()
# 关键词分布
keyword_hour_count = df.groupby(['keyword', 'hour'])['title'].count().reset_index(name='count')
plt.figure(figsize=(12, 6))
sns.lineplot(x='hour', y='count', hue='keyword', data=keyword_hour_count)
plt.title('Keyword Hourly News Count', fontsize=15)
plt.xlabel('Hour', fontsize=12)
plt.ylabel('Count', fontsize=12)
plt.show()
db.close()
```
4. Web 可视化:
```python
from flask import Flask, render_template, request
import pymysql
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/search')
def search():
db = pymysql.connect(host='localhost', user='root', password='password', database='news', charset='utf8mb4')
keyword = request.args.get('keyword')
if keyword:
sql = "SELECT * FROM news WHERE title LIKE %s"
cursor = db.cursor()
cursor.execute(sql, ('%' + keyword + '%',))
news_list = cursor.fetchall()
else:
news_list = []
db.close()
return render_template('search.html', keyword=keyword, news_list=news_list)
@app.route('/analysis')
def analysis():
analysis_news()
return 'Analysis Completed!'
if __name__ == '__main__':
app.run(debug=True)
```
5. 网页模板:
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>News Crawler</title>
</head>
<body>
<h1>News Crawler</h1>
<form action="/search" method="get">
<input type="text" name="keyword">
<input type="submit" value="Search">
</form>
<br>
<a href="/analysis">Analysis</a>
</body>
</html>
```
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Search Results: {{ keyword }}</title>
</head>
<body>
<h1>Search Results: {{ keyword }}</h1>
{% if news_list %}
<ul>
{% for news in news_list %}
<li>
<a href="{{ news[3] }}">{{ news[1] }}</a>
<span>{{ news[2] }}</span>
<p>{{ news[4][:100] }}</p>
</li>
{% endfor %}
</ul>
{% else %}
<p>No results found.</p>
{% endif %}
</body>
</html>
```
运行方式:
1. 安装 Python 爬虫库 requests、BeautifulSoup 和数据库操作库 pymysql。
2. 确定要爬取的新闻网站,并运行 get_news 函数爬取新闻信息,将结果保存到 MySQL 数据库中。
3. 运行 analysis_news 函数进行数据分析和可视化,生成图表展示新闻热点话题、关键词、时间分布等信息。
4. 运行 Flask Web 服务器,将分析结果以网页的形式展示出来,并提供搜索和筛选功能。
参考资料:
1. requests:https://requests.readthedocs.io/en/master/
2. BeautifulSoup:https://www.crummy.com/software/BeautifulSoup/bs4/doc/
3. pymysql:https://pymysql.readthedocs.io/en/latest/
4. pandas:https://pandas.pydata.org/docs/
5. matplotlib:https://matplotlib.org/stable/contents.html
6. seaborn:https://seaborn.pydata.org/
7. Flask:https://flask.palletsprojects.com/en/2.0.x/
阅读全文