Python 豆瓣电影评论爬虫实战与数据分析
本文将详细介绍如何使用 Python 爬虫抓取豆瓣网电影评论用户的观影习惯数据,并进行简单的数据处理和分析。通过本教程,读者可以掌握网络数据采集、反爬策略应对以及数据存储的基本流程。
一、配置环境
在开始爬取豆瓣网电影评论数据之前,我们需要配置好 Python 开发环境和相关依赖库。
Python 爬虫技术用于抓取豆瓣电影评论数据,涵盖环境配置、反爬策略(代理 IP、请求头伪装)、Selenium 登录模拟、数据解析与存储(数据库及 CSV)。文章提供完整代码示例,强调合法合规使用及隐私保护,适合初学者进行网络数据采集与分析实践。

本文将详细介绍如何使用 Python 爬虫抓取豆瓣网电影评论用户的观影习惯数据,并进行简单的数据处理和分析。通过本教程,读者可以掌握网络数据采集、反爬策略应对以及数据存储的基本流程。
在开始爬取豆瓣网电影评论数据之前,我们需要配置好 Python 开发环境和相关依赖库。
建议使用 Python 3.x 版本。可以在官网下载并安装对应版本的 Python:https://www.python.org/downloads/。
接下来,我们需要安装两个 Python 库:Requests 和 BeautifulSoup。
可以使用 pip 命令自动安装这两个库:
pip install requests
pip install beautifulsoup4
如果我们需要对抓取的数据进行可视化分析,可以使用 Matplotlib 库。可以使用 pip 命令安装:
pip install matplotlib
此外,若需操作数据库,建议安装 PyMySQL:
pip install pymysql
安装完成后,我们就可以开始爬取豆瓣网电影评论数据了。
豆瓣网对爬虫有一定的反爬虫策略,根据实战经验,反爬机制一般作用于用户 ID、用户 IP 和请求头的过滤。为了避免被封禁 IP,代码中需要加入一些反爬虫措施:
使用代理可以帮助我们隐藏自己的真实 IP 地址,避免被封禁 IP 或者限制访问。在爬取豆瓣网电影评论数据时,如果频繁地访问同一个 IP 地址,豆瓣网可能会禁止我们的访问,因此使用代理也可以防止被封禁。
以下是使用用户名 + 密码授权获取 IP 的代码示例(通用格式):
import requests
url = 'http://www.ip138.com/'
proxies = {
'http': 'http://账号:密码@ip:port',
'https': 'http://账号:密码@ip:port'
}
response = requests.get(url, proxies=proxies)
测试代理 IP 是否可用是为了确保我们使用的代理 IP 能够正常工作,防止由于代理 IP 失效或无效而导致爬虫请求失败。
以下是一段测试代理 IP 的代码示例:
import requests
def test_proxy_ip(proxy_ip, target_url):
proxies = {
'http': 'http://' + proxy_ip,
'https': 'http://' + proxy_ip
}
try:
response = requests.get(target_url, proxies=proxies, timeout=5)
if response.status_code == 200:
return True
else:
return False
except:
return False
当我们在爬取豆瓣网电影评论数据时,可以使用上述代码测试代理 IP 是否可用。如果代理 IP 可用,则使用该代理 IP 发送请求;如果代理 IP 无效或被封禁,则需要更换新的代理 IP。
爬取豆瓣网电影评论用户的观影习惯数据要设置大量请求头随机使用是为了防止网站监测到我们的请求头是模拟的,并防止被反爬虫机制封禁 IP。因此,我们需要尽可能多的提供不同的请求头信息,对请求头进行随机使用,以降低被监测到的概率。
以下是一个随机使用请求头的示例代码:
import random
USER_AGENTS = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19582',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299',
]
def get_random_user_agent():
return random.choice(USER_AGENTS)
headers = {
'User-Agent': get_random_user_agent(),
'Referer': 'https://www.douban.com',
'Cookie': 'your_cookie' # 实际使用时需替换为有效 Cookie
}
在使用随机请求头的同时,仍然需要保持一定的爬取速度和请求间隔,以避免被封禁。
以下是一个使用 Selenium 模拟登录豆瓣网并保存 cookie 的示例代码:
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
import pickle
login_url = 'https://accounts.douban.com/passport/login?source=movie'
username = 'your_username'
password = 'your_password'
cookie_file = 'cookies.pkl'
# 启动浏览器
driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(10)
# 访问登录页面
driver.get(login_url)
# 输入用户名和密码
driver.find_element(By.ID, 'username').send_keys(username)
driver.find_element(By.ID, 'password').send_keys(password)
# 等待用户输入验证码
time.sleep(30)
# 点击登录按钮
driver.find_element(By.CLASS_NAME, 'account-form-field-submit ').click()
# 等待新页面加载完成
time.sleep(10)
# 保存 cookie 到文件
cookies = driver.get_cookies()
with open(cookie_file, 'wb') as f:
pickle.dump(cookies, f)
# 关闭浏览器
driver.quit()
注意,这里使用了 pickle 模块将 cookies 对象序列化并保存到文件中,以便后续使用。
前面我们已经把爬取豆瓣网的准备工作全部完成,接下来就是爬取豆瓣网中某一部热门电影的各种数据了。
爬取热门电影的全部长短评论可以获得以下信息:
以下是一个使用 BeautifulSoup 和 requests 库爬取豆瓣网某部电影全部长、短评论说明的示例代码:
import requests
from bs4 import BeautifulSoup
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36'
}
url = 'https://movie.douban.com/subject/1292052/'
response = requests.get(url, headers=headers)
html = response.text
soup = BeautifulSoup(html, 'html.parser')
# 查找长评和短评标签
long_comments = soup.select_one('#hot-comments > div > div.article > span')
short_comments = soup.select_one('#comments > div > h2 > span')
if long_comments and short_comments:
long_comments_count = long_comments.text.replace('全部', '').replace('条', '').strip()
short_comments_count = short_comments.text.replace('全部', '').replace('条', '').strip()
print(f"长评:{long_comments_count}")
print(f"短评:{short_comments_count}")
# 查找所有长评和短评内容
long_comments_list = soup.select('#hot-comments > div > div.article > div > div.comment > p')
short_comments_list = soup.select('#comments > div > div.comment > p')
for comment in long_comments_list:
print(comment.text.strip())
for comment in short_comments_list:
print(comment.text.strip())
获取用户观影数据可以帮助我们了解用户的观影喜好和习惯,可以通过分析用户的观影历史和评分记录等内容。
以下是获取用户观影数据的 Python 代码示例:
import requests
import json
session = requests.session()
url = 'https://accounts.douban.com/j/mobile/login/basic'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
'Referer': 'https://accounts.douban.com/passport/login',
}
data = {
'name': 'your_username',
'password': 'your_password',
'remember': 'false',
}
session.post(url, headers=headers, data=data)
uid = 'your_user_id'
url = 'https://movie.douban.com/subject_suggest?q=%E7%94%B5%E5%BD%B1'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
'Referer': 'https://www.douban.com/',
}
response = session.get(url, headers=headers)
data = json.loads(response.text)
movie_id = data[0]['id']
url = f'https://movie.douban.com/subject/{movie_id}/'
response = session.get(url, headers=headers)
url = response.url + 'comments?start=0&limit=20&status=P&sort=new_score'
response = session.get(url, headers=headers)
data = response.text
print(data)
将获取的数据存入数据库的好处包括数据持久化、便于分析和数据管理。
以下是将获取的去重后的数据存入数据库的 Python 代码示例:
import requests
import json
import pymysql
# 连接数据库
try:
db = pymysql.connect(host='localhost', user='root', password='123456', database='test')
cursor = db.cursor()
except Exception as e:
print(f"数据库连接失败:{e}")
exit()
# 假设 result2 是去重后的数据列表
result2 = []
# ... (此处省略数据收集逻辑)
for item in result2:
sql = "INSERT INTO movie_comment (id, user_name, rating, create_time, content) VALUES (%s, %s, %s, %s, %s)"
cursor.execute(sql, (item['id'], item['user_name'], item['rating'], item['create_time'], item['content']))
db.commit()
db.close()
注意,实际使用中应使用参数化查询以防止 SQL 注入,并根据实际情况修改数据库配置。
以下是一个基于 Python 的爬虫示例,可以爬取指定电影的所有评论用户的观影习惯数据,并保存至 CSV 文件中:
import requests
from bs4 import BeautifulSoup
import csv
import time
from random import randint
MOVIE_URL = 'https://movie.douban.com/subject/xxxxxx/'
CSV_FILE = 'douban.csv'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
'Referer': MOVIE_URL,
}
proxies = ['http://xxx.xxx.xx.xx:xxxx', 'http://yyy.yyy.yy.yy:yyyy']
WAIT_TIME = 1
def get_html(url):
try:
proxy = {'http': proxies[randint(0, len(proxies)-1)]} if proxies else None
response = requests.get(url, headers=headers, proxies=proxy)
if response.status_code == 200:
return response.text
except requests.exceptions.RequestException as e:
print(e)
return None
def get_user_link(comment_soup):
try:
user_tag = comment_soup.find('span', class_='comment-info').find('a')
user_link = user_tag.get('href')
return user_link
except:
return None
def get_user_data(user_link):
user_data = {}
html = get_html(user_link)
time.sleep(WAIT_TIME)
if html:
soup = BeautifulSoup(html, 'html.parser')
try:
type_tags = soup.find_all('span', class_='tags-body')
type_list = [t.text.strip() for t in type_tags]
user_data['type'] = ','.join(type_list)
except:
user_data['type'] = ''
user_data['top_movies'] = ''
try:
movie_tags = soup.find_all('div', class_='info')
movie_list = []
for tag in movie_tags:
movie_name_tag = tag.find('a', class_='title')
if movie_name_tag and movie_name_tag['href'] != MOVIE_URL:
movie_list.append(movie_name_tag.text)
if len(movie_list) >= 5:
break
user_data['top_movies'] = ','.join(movie_list)
except:
pass
return user_data
def main():
print('开始爬取...')
comments = []
page = 0
while True:
page += 1
url = MOVIE_URL + 'comments?start=' + str((page-1) * 20)
html = get_html(url)
time.sleep(WAIT_TIME)
if html:
soup = BeautifulSoup(html, 'html.parser')
comment_tags = soup.find_all('div', class_='comment-item')
if comment_tags:
comments.extend(comment_tags)
else:
break
else:
break
user_data_list = []
for comment in comments:
user_link = get_user_link(comment)
if user_link:
user_data = get_user_data(user_link)
user_data_list.append(user_data)
print('已爬取 {} 个用户观影数据'.format(len(user_data_list)))
time.sleep(WAIT_TIME)
with open(CSV_FILE, mode='w', encoding='utf-8', newline='') as f:
fieldnames = ['type', 'top_movies']
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
for data in user_data_list:
writer.writerow(data)
print('爬取完成,数据已保存至 {} 文件中。'.format(CSV_FILE))
if __name__ == '__main__':
main()
需要注意的是,以上代码仅供参考,实际使用时需要根据具体情况进行调整。另外,爬虫涉及到的法律问题和道德问题需要认真考虑,不要用于非法用途或侵犯他人隐私等行为。
需要注意的几点:
爬取豆瓣网电影评论用户的观影习惯数据能够得出用户的观影时间偏好、观影类型偏好、观影评分偏好、观影影院偏好和地理位置偏好等信息。通过这些数据分析,可以更好地为用户推荐电影和为广告主提供更精准的广告投放服务。
在实际操作中,务必遵守目标网站的 robots.txt 协议及相关法律法规,合理控制请求频率,尊重用户隐私,确保技术应用的合规性。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online