【Python】从0开始写爬虫——豆瓣电影

简介: 1. 最近略忙。。java在搞soap,之前是用工具自动生成代码的。最近可能会写一个soap的java调用 2. 这个豆瓣电影的爬虫。扒信息的部分暂时先做到这了。扒到的信息如下 from scrapy import app import re header = { 'User-Agent': 'Mozilla/5.

1. 最近略忙。。java在搞soap,之前是用工具自动生成代码的。最近可能会写一个soap的java调用

2. 这个豆瓣电影的爬虫。扒信息的部分暂时先做到这了。扒到的信息如下

from scrapy import app
import re

header = {
    'User-Agent':
        'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36',
    'Host': 'movie.douban.com',
    'Accept-Language': 'zh-CN,zh;q=0.9'
}

movie_url = "https://movie.douban.com/subject/27132728/?tag=%E7%83%AD%E9%97%A8&from=gaia"

m_id = re.search("[0-9]+", movie_url).group()

# 获取soup对象
soup = app.get_soup(url=movie_url, headers=header, charset="utf-8")
content = soup.find(id="content")

# 抓取电影名字和上映年份
m_name = content.find("h1").find("span").string
m_year = content.find(class_="year").string
m_year = m_year[1:-1]  # 去掉头尾的括号

# 抓取导演
info = content.find(id="info")
m_directer = info.find(attrs={"rel": "v:directedBy"}).string# 上映日期
m_date = info.find(attrs={"property": "v:initialReleaseDate"}).string
m_date = re.search("[-,0-9]+", m_date).group()

# 类型
types = info.find_all(attrs={"property": "v:genre"}, limit=2)
m_types = []
for type_ in types:
    m_types.append(type_.string)


# 抓取主演,只取前面五个
actors = info.find(class_="actor").find_all(attrs={"rel": "v:starring"}, limit=5)
m_actors = []
for actor in actors:
    m_actors.append(actor.string)

# 片长
m_time = info.find(attrs={"property": "v:runtime"}).string
m_time = re.search("[0-9]+", m_time).group()


# 评分
score_info = soup.find(id="interest_sectl")
m_score = score_info.find("strong").string


m_stars = score_info.find_all(class_="rating_per")
m_rate = []
for star in m_stars:
    m_rate.append(star.string[:-1])

m_votes = score_info.find(attrs={"property": "v:votes"}).string

print("id", m_id, "名称", m_name, "年份 ", m_year, "导演 ", m_directer, "主演", m_actors)

print("上映日期", m_date, "类型", m_types, "片长", m_time)

print("评分", m_score, "星评(从5星到1星)", m_rate, "评价总数", m_votes)

输出如下

id 27132728 名称 致命警告 El aviso 年份  2018 导演  丹尼尔·卡尔帕索罗 主演 ['奥拉·加里多', '劳尔·阿雷瓦洛', '贝伦·奎斯塔', 'Sergio Mur', 'Aitor Luna']
上映日期 2018-03-23 类型 ['惊悚'] 片长 92
评分 6.4 星评(从5星到1星) ['14.2', '19.9', '41.1', '21.3', '3.5'] 评价总数 445

 

把这些狗东西封装成一个方法。并且随便找几个豆瓣电影的url试一下。在多尝试几个url之后,会报一些问题,主要是没有进行空判断, 所以稍微修改了一点

from scrapy import app
import re


def douban_movie(movie_url):

    header = {
        'User-Agent':
            'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36',
        'Host': 'movie.douban.com',
        'Accept-Language': 'zh-CN,zh;q=0.9'
    }
    m_id = re.search("[0-9]+", movie_url).group()

    # 获取soup对象
    soup = app.get_soup(url=movie_url, headers=header, charset="utf-8")
    content = soup.find(id="content")

    # 抓取电影名字和上映年份
    m_name = content.find("h1").find("span").string
    m_year = content.find(class_="year").string
    m_year = m_year[1:-1]  # 去掉头尾的括号

    # 抓取导演
    info = content.find(id="info")
    m_directer = info.find(attrs={"rel": "v:directedBy"}).string

    # 上映日期
    m_date = info.find(attrs={"property": "v:initialReleaseDate"}).string
    m_date = re.search("[-,0-9]+", m_date).group()

    # 类型
    types = info.find_all(attrs={"property": "v:genre"}, limit=2)
    m_types = []
    for type_ in types:
        m_types.append(type_.string)

    # 抓取主演,只取前面五个
    actors = info.find(class_="actor").find_all(attrs={"rel": "v:starring"}, limit=5)
    m_actors = []
    for actor in actors:
        m_actors.append(actor.string)

    # 片长
    m_time = info.find(attrs={"property": "v:runtime"})
    m_time = re.search("[0-9]+", m_time.string).group() if m_time else 0

    # 评分
    score_info = soup.find(id="interest_sectl")
    m_score = score_info.find("strong").string

    m_stars = score_info.find_all(class_="rating_per")
    m_rate = []
    for star in m_stars:
        m_rate.append(star.string[:-1])

    m_votes = score_info.find(attrs={"property": "v:votes"})
    m_votes = m_votes.string if m_votes else 0

    print("id", m_id, "名称", m_name, "年份 ", m_year, "导演 ", m_directer, "主演", m_actors)

    print("上映日期", m_date, "类型", m_types, "片长", m_time)

    print("评分", m_score, "星评(从5星到1星)", m_rate, "评价总数", m_votes)


douban_movie("https://movie.douban.com/subject/30236775/?from=showing")
douban_movie("https://movie.douban.com/subject/26842702/?tag=%E7%83%AD%E9%97%A8&from=gaia")
douban_movie("https://movie.douban.com/subject/26973784/?tag=%E6%9C%80%E6%96%B0&from=gaia")
douban_movie("https://movie.douban.com/subject/30249296/?tag=%E7%83%AD%E9%97%A8&from=gaia")

输出如下

id 30236775 名称 旅行吧!井底之蛙 年份  2018 导演  陈设 主演 ['王雪沁', '吴凡', '周宗禹', '强光宗', '张艺文']
上映日期 2018-08-18 类型 ['动画', '奇幻'] 片长 78
评分 None 星评(从5星到1星) [] 评价总数 0
id 26842702 名称 燃烧 버닝 年份  2018 导演  李沧东 主演 ['刘亚仁', '史蒂文·元', '全钟瑞', '金秀京', '崔承浩']
上映日期 2018-05-16 类型 ['剧情', '悬疑'] 片长 148
评分 7.9 星评(从5星到1星) ['25.9', '48.1', '21.4', '3.2', '1.3'] 评价总数 81519
id 26973784 名称 设局 La niebla y la doncella 年份  2017 导演  安德烈斯·M·科佩尔 主演 ['基姆·古铁雷斯', '薇洛妮卡·恩切圭', '奥拉·加里多', '罗伯托·阿拉莫']
上映日期 2017-09-08 类型 ['惊悚'] 片长 0
评分 5.2 星评(从5星到1星) ['1.2', '9.8', '42.0', '40.0', '7.1'] 评价总数 320
id 30249296 名称 我们的侣行 第二季 年份  2018 导演  张昕宇 主演 ['张昕宇', '梁红']
上映日期 2018-06-12 类型 ['真人秀'] 片长 0
评分 8.9 星评(从5星到1星) ['59.3', '27.8', '11.1', '1.9', '0.0'] 评价总数 342

 

又稍微修改了一下

1. 把原方法加了一个返回值返回一个存储数据的字典

2.对数据做了一些转换,主要是把字符串转成数字

3.对电影和电视剧做了一个区分。

from scrapy import app
import re
import datetime


def douban_movie(movie_url):

    header = {
        'User-Agent':
            'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36',
        'Host': 'movie.douban.com',
        'Accept-Language': 'zh-CN,zh;q=0.9'
    }

    movie = {}

    m_id = re.search("[0-9]+", movie_url).group()
    movie["id"] = m_id
    # 获取soup对象
    soup = app.get_soup(url=movie_url, headers=header, charset="utf-8")
    content = soup.find(id="content")

    kinds = content.find(class_="episode_list")
    movie["type"] = 0 if kinds else 1             # 0 :电视剧,1:电影。如果有分集数,为电视剧, 否则就是电影
    # 抓取电影名字和上映年份
    m_name = content.find("h1").find("span").string
    movie["name"] = m_name;
    m_year = content.find(class_="year").string
    m_year = m_year[1:-1]  # 去掉头尾的括号
    movie["year"] = m_year
    # 抓取导演
    info = content.find(id="info")
    m_directer = info.find(attrs={"rel": "v:directedBy"}).string
    movie["directer"] = m_directer
    # 上映日期
    m_date = info.find(attrs={"property": "v:initialReleaseDate"}).string
    m_date = re.search("[-,0-9]+", m_date).group()
    movie["date"] = datetime.datetime.strptime(m_date, '%Y-%m-%d')

    # 类型
    categories = info.find_all(attrs={"property": "v:genre"}, limit=2)
    m_categories = []
    for category in categories:
        m_categories.append(category.string)
    movie["categories"] = m_categories

    # 抓取主演,只取前面五个
    actors = info.find(class_="actor").find_all(attrs={"rel": "v:starring"}, limit=5)
    m_actors = []
    for actor in actors:
        m_actors.append(actor.string)
    movie["actors"] = m_actors
    # 片长
    m_time = info.find(attrs={"property": "v:runtime"})
    m_time = int(re.search("[0-9]+", m_time.string).group()) if m_time else 0
    movie["time"] = m_time
    # 评分
    score_info = soup.find(id="interest_sectl")
    m_score = score_info.find("strong").string if score_info.find("strong") else 0.0
    movie["score"] = float(m_score) if m_score else 0.0
    m_stars = score_info.find_all(class_="rating_per")
    m_rate = []
    for star in m_stars:
        m_rate.append(float(star.string[:-1]))
    movie["stars"] = m_rate
    m_votes = score_info.find(attrs={"property": "v:votes"})
    m_votes = int(m_votes.string) if m_votes else 0
    movie["vote"] = m_votes
    return movie


print(douban_movie("https://movie.douban.com/subject/30236775/?from=showing"))
print(douban_movie("https://movie.douban.com/subject/26842702/?tag=%E7%83%AD%E9%97%A8&from=gaia"))
print(douban_movie("https://movie.douban.com/subject/26973784/?tag=%E6%9C%80%E6%96%B0&from=gaia"))
print(douban_movie("https://movie.douban.com/subject/30249296/?tag=%E7%83%AD%E9%97%A8&from=gaia"))

输出

{'id': '30236775', 'type': 1, 'name': '旅行吧!井底之蛙', 'year': '2018', 'directer': '陈设', 'date': datetime.datetime(2018, 8, 18, 0, 0), 'categories': ['动画', '奇幻'], 'actors': ['王雪沁', '吴凡', '周宗禹', '强光宗', '张艺文'], 'time': 78, 'score': 0.0, 'stars': [], 'vote': 0}
{'id': '26842702', 'type': 1, 'name': '燃烧 버닝', 'year': '2018', 'directer': '李沧东', 'date': datetime.datetime(2018, 5, 16, 0, 0), 'categories': ['剧情', '悬疑'], 'actors': ['刘亚仁', '史蒂文·元', '全钟瑞', '金秀京', '崔承浩'], 'time': 148, 'score': 7.9, 'stars': [25.9, 48.1, 21.5, 3.2, 1.3], 'vote': 83194}
{'id': '26973784', 'type': 1, 'name': '设局 La niebla y la doncella', 'year': '2017', 'directer': '安德烈斯·M·科佩尔', 'date': datetime.datetime(2017, 9, 8, 0, 0), 'categories': ['惊悚'], 'actors': ['基姆·古铁雷斯', '薇洛妮卡·恩切圭', '奥拉·加里多', '罗伯托·阿拉莫'], 'time': 0, 'score': 5.2, 'stars': [1.2, 9.8, 41.8, 40.2, 7.0], 'vote': 321}
{'id': '30249296', 'type': 0, 'name': '我们的侣行 第二季', 'year': '2018', 'directer': '张昕宇', 'date': datetime.datetime(2018, 6, 12, 0, 0), 'categories': ['真人秀'], 'actors': ['张昕宇', '梁红'], 'time': 0, 'score': 8.9, 'stars': [59.3, 28.8, 10.2, 1.7, 0.0], 'vote': 400}

 

相关文章
|
11天前
|
数据采集 存储 API
网络爬虫与数据采集:使用Python自动化获取网页数据
【4月更文挑战第12天】本文介绍了Python网络爬虫的基础知识,包括网络爬虫概念(请求网页、解析、存储数据和处理异常)和Python常用的爬虫库requests(发送HTTP请求)与BeautifulSoup(解析HTML)。通过基本流程示例展示了如何导入库、发送请求、解析网页、提取数据、存储数据及处理异常。还提到了Python爬虫的实际应用,如获取新闻数据和商品信息。
|
15天前
|
数据采集 Python
【python】爬虫-西安医学院-校长信箱
本文以西安医学院-校长信箱为基础来展示爬虫案例。来介绍python爬虫。
【python】爬虫-西安医学院-校长信箱
|
21天前
|
数据采集 安全 Python
python并发编程:Python实现生产者消费者爬虫
python并发编程:Python实现生产者消费者爬虫
24 0
python并发编程:Python实现生产者消费者爬虫
|
1天前
|
数据采集 存储 JSON
Python爬虫面试:requests、BeautifulSoup与Scrapy详解
【4月更文挑战第19天】本文聚焦于Python爬虫面试中的核心库——requests、BeautifulSoup和Scrapy。讲解了它们的常见问题、易错点及应对策略。对于requests,强调了异常处理、代理设置和请求重试;BeautifulSoup部分提到选择器使用、动态内容处理和解析效率优化;而Scrapy则关注项目架构、数据存储和分布式爬虫。通过实例代码,帮助读者深化理解并提升面试表现。
10 0
|
5天前
|
数据采集 JavaScript 前端开发
使用Python打造爬虫程序之破茧而出:Python爬虫遭遇反爬虫机制及应对策略
【4月更文挑战第19天】本文探讨了Python爬虫应对反爬虫机制的策略。常见的反爬虫机制包括User-Agent检测、IP限制、动态加载内容、验证码验证和Cookie跟踪。应对策略包括设置合理User-Agent、使用代理IP、处理动态加载内容、验证码识别及维护Cookie。此外,还提到高级策略如降低请求频率、模拟人类行为、分布式爬虫和学习网站规则。开发者需不断学习新策略,同时遵守规则和法律法规,确保爬虫的稳定性和合法性。
|
16天前
|
数据采集 存储 前端开发
Python爬虫如何快速入门
写了几篇网络爬虫的博文后,有网友留言问Python爬虫如何入门?今天就来了解一下什么是爬虫,如何快速的上手Python爬虫。
20 0
|
21天前
|
人工智能 机器人 数据挖掘
【python】电影评分数据集的分析(python实现)(源码+报告)【独一无二】
【python】电影评分数据集的分析(python实现)(源码+报告)【独一无二】
|
24天前
|
机器学习/深度学习 数据采集 算法
基于Apriori关联规则的电影推荐系统(附python代码)
这是一个基于Apriori算法的电影推荐系统概览。系统通过挖掘用户评分数据来发现关联规则,例如用户观看某部电影后可能感兴趣的其他电影。算法核心是逐层生成频繁项集并设定最小支持度阈值,之后计算规则的置信度。案例中展示了数据预处理、频繁项集生成以及规则提取的过程,具体包括用户评分电影的统计分析,如1-5部电影的评分组合。最后,通过Python代码展示了Apriori算法的实现,生成推荐规则,并给出了一个简单的推荐示例。整个过程旨在提高推荐的精准度,基于用户已评分的电影推测他们可能尚未评分但可能喜欢的电影。
基于Apriori关联规则的电影推荐系统(附python代码)
|
29天前
|
数据采集 存储 Web App开发
一键实现数据采集和存储:Python爬虫、Pandas和Excel的应用技巧
一键实现数据采集和存储:Python爬虫、Pandas和Excel的应用技巧
|
13天前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。