栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python爬取豆瓣电影_python爬取豆瓣top250?

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python爬取豆瓣电影_python爬取豆瓣top250?

文章目录

零、前言:一、分析

1.1 爬虫分析1.2 网站分析

1.2.1 判断网页类型1.2.2 url及其参数 二、爬虫

2.1 数据获取 requests2.2 数据清洗 re2.3 数据存储 mysql2.4 运行 三、完整代码四、结尾


零、前言:

本文适合初学爬虫,练习使用

实现功能:
爬豆瓣top250,存入mysql 数据库。效果图:


一、分析 1.1 爬虫分析

爬虫三步骤:

    数据获取数据清洗数据存储

数据获取,用 requests 库,urllib 库等。本文用 requests演示
数据清洗,有 xpath、bs4、re正则、pyquery 等,本文用 正则(re)演示
数据存储,有 txt、csv(csv库)、xlsx(pandas库或)、数据库(mysql,mongdb等),本文用 mysql数据库(pymysql)演示


1.2 网站分析

搜索引擎输入 豆瓣top250


1.2.1 判断网页类型

通过 ctrl+U 查看网页源代码

可以发现,电影数据都在 html 里面。因此,该网页是静态网页。如果是动态网页,需要解析真实地址抓取,或者用 selenium


1.2.2 url及其参数

抓包
f12 是浏览器自带的抓包工具
通过 右键->检查->network(或网络)->ctrl+r刷新,可以看到刷过很多文件。可以找到网页的 html 文件。

在 header 里面,可以看到请求头相关信息,比如 请求 url,cookie,user-agent,request-method等。

请求方式是 get 请求。get 和 post 请求在爬虫中常用到

user-agent 是浏览器信息。比如上面的 user-agent是

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.82 Safari/537.36

里面包含了浏览器的信息。如果是手机的话或者linux,或者谷歌浏览器,里面会有 chrome,linux等。通常,网站会检查请求的 user-agent,防止爬虫程序获取数据。

当爬网站发现,响应数据不正常的时候,可以添加 user-agent 和 cookie 尝试

url:https://movie.douban.com/top250?start=0&filter=
该 url 里面包含了两个参数 start 和 filter
眼尖的朋友可能注意到了,start 表示开始,filter 表示过滤

当我们点亮 我没看过的后,刷新可以看到,filter 变成了 unwatched。而点击下一页,可以爬到,start 变成了25
所以,可以通过修改 start 的值来翻页。而 filter 参数没太大用处


二、爬虫 2.1 数据获取 requests

python的强大之处,其中一点是第三方库很完善。
首先创造一个 DouBan 类

class DouBan:
    def __init__(self, user, password, host='localhost', port=3306):
        self.url = "https://movie.douban.com/top250?start={}&filter="
        self.headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"}

通过 requests 库获取数据

    def dataGet(self, start):
        return requests.get(self.url.format(start), headers=self.headers).text

该函数,首先接收页面 start,通过 requests 的 get 方法,返回 html 的字符串


2.2 数据清洗 re
    def dataClean(self, html:str):
        result = []
        # 将 换行符替换掉
        html = html.replace("n", "")
        # rep 是匹配每个电影的数据,再用 for 循环,逐个清洗数据
        rep = re.compile('.*?')
        for info in re.findall(rep, html):
            # 名字
            names = re.findall('(.*?)', info)
            chineseName = names[0]
            if len(names)==2:
                englishName = names[1].replace("/", "").strip().replace(" ", "")
            else:
                englishName = "-"
            otherName = re.findall('(.*?)', info)[0].strip("/").replace(" ", "")
            # 评分, 评价人数
            star = re.findall('(.*?)', info)[0]
            starPeople = re.findall('(.*?)人评价', info)[0]
            starPeople = self.Format(starPeople)
            # 语录
            try:
                nidehanwang = re.findall('(.*?)', info)[0]
            except:
                nidehanwang = "-"
            # 其余数据
            others = re.findall('

(.*?)

', info)[0].strip().replace("/", "").split("  ") type = others[-1] country = others[-2] if len(others) == 4: direct = others[0].split(":")[-1].strip() others = others[1].split("
") year = others[-1].strip() actors = others[0].split(":")[-1] else: if "主演" not in others[0]: direct = others[0].split("
")[0].split(":")[1] year = others[0].split("
")[1].strip() actors = "-" if len(str(year))>4: year = re.findall("([0-9]+)", year)[-1] result.append([chineseName, englishName, otherName, direct, actors, year, country, type, star, starPeople, nidehanwang]) return result # 数字太长的,改为 万 为单位 def Format(self, num): if len(str(num))>4: return str(round(int(num)/10000, 1))+"万"

2.3 数据存储 mysql

如果你不想用 mysql ,也可以选择别的存储方式。比如 xlsx,csv,txt,或者其他的数据库

python连接mysql数据库,用 pymysql 库。要经过:连接数据库->建表->存储->关闭连接

连接并建表可以一步完成。因为我们只建一次表,只连一次库

    def sqlConnect(self, user, password, host, port):
        try:
            self.conn = pysql.connect(user=user, password=password, host=host, port=port)
        except Exception as e:
            print("数据库连接失败")
            exit(0)
        print("数据库连接成功!")
        self.cursor = self.conn.cursor()

        self.cursor.execute("create database if not exists douban")
        self.cursor.execute("use douban")
        try:
            self.cursor.execute("drop table douban")
        except:
            pass
        sql = '''
                create table douban (
                id int unsigned auto_increment,
                `中文名` varchar(15),
                `英文名` varchar(70),
                `别名` varchar(100),
                `导演` varchar(70),
                `演员` varchar(50),
                `上映年份` int,
                `上映国家` varchar(30),
                `类型` varchar(30),
                `评分` char(3),
                `评价人数` varchar(10),
                `语录` varchar(50),
                primary key (`id`))
            '''
        self.cursor.execute(sql)

存储

    def sqlSave(self, datas:list):
        sql = '''
                insert into douban (
                `中文名`, `英文名`, `别名`, `导演`, `演员`, `上映年份`, `上映国家`, `类型`, `评分`, `评价人数`, `语录`
                ) value("{}", "{}", "{}", "{}", "{}", {}, "{}", "{}", "{}", "{}", "{}")
            '''
        for line in datas:
            newsql = sql
            for i in line:
                newsql = newsql.replace("{}", i, 1)
            self.cursor.execute(newsql)
        self.conn.commit()

2.4 运行
    def run(self):
        for i in range(10):
            print("正在爬取第<{}>/<{}>页".format(i, 10))
            html = self.dataGet(i*25)
            data = self.dataClean(html)
            self.sqlSave(data)
        print("爬取成功!")
        self.conn.close()

三、完整代码
import requests
import re
import pymysql as pysql


class DouBan:
    def __init__(self, user, password, host='localhost', port=3306):
        self.url = "https://movie.douban.com/top250?start={}&filter="
        self.headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"}
        self.sqlConnect(user, password, host, port)

    def dataGet(self, start):
        return requests.get(self.url.format(start), headers=self.headers).text

    def dataClean(self, html:str):
        result = []
        html = html.replace("n", "")
        rep = re.compile('.*?')
        for info in re.findall(rep, html):
            # 名字
            names = re.findall('(.*?)', info)
            chineseName = names[0]
            if len(names)==2:
                englishName = names[1].replace("/", "").strip().replace(" ", "")
            else:
                englishName = "-"
            otherName = re.findall('(.*?)', info)[0].strip("/").replace(" ", "")
            # 评分, 评价人数
            star = re.findall('(.*?)', info)[0]
            starPeople = re.findall('(.*?)人评价', info)[0]
            starPeople = self.Format(starPeople)
            # 语录
            try:
                nidehanwang = re.findall('(.*?)', info)[0]
            except:
                nidehanwang = "-"
            # other
            others = re.findall('

(.*?)

', info)[0].strip().replace("/", "").split("  ") type = others[-1] country = others[-2] if len(others) == 4: direct = others[0].split(":")[-1].strip() others = others[1].split("
") year = others[-1].strip() actors = others[0].split(":")[-1] else: if "主演" not in others[0]: direct = others[0].split("
")[0].split(":")[1] year = others[0].split("
")[1].strip() actors = "-" if len(str(year))>4: year = re.findall("([0-9]+)", year)[-1] result.append([chineseName, englishName, otherName, direct, actors, year, country, type, star, starPeople, nidehanwang]) return result def sqlConnect(self, user, password, host, port): try: self.conn = pysql.connect(user=user, password=password, host=host, port=port) except Exception as e: print("数据库连接失败") exit(0) print("数据库连接成功!") self.cursor = self.conn.cursor() self.cursor.execute("create database if not exists douban") self.cursor.execute("use douban") try: self.cursor.execute("drop table douban") except: pass sql = ''' create table douban ( id int unsigned auto_increment, `中文名` varchar(15), `英文名` varchar(70), `别名` varchar(100), `导演` varchar(70), `演员` varchar(50), `上映年份` int, `上映国家` varchar(30), `类型` varchar(30), `评分` char(3), `评价人数` varchar(10), `语录` varchar(50), primary key (`id`)) ''' self.cursor.execute(sql) def sqlSave(self, datas:list): sql = ''' insert into douban ( `中文名`, `英文名`, `别名`, `导演`, `演员`, `上映年份`, `上映国家`, `类型`, `评分`, `评价人数`, `语录` ) value("{}", "{}", "{}", "{}", "{}", {}, "{}", "{}", "{}", "{}", "{}") ''' for line in datas: newsql = sql for i in line: newsql = newsql.replace("{}", i, 1) self.cursor.execute(newsql) self.conn.commit() def Format(self, num): if len(str(num))>4: return str(round(int(num)/10000, 1))+"万" def run(self): for i in range(10): print("正在爬取第<{}>/<{}>页".format(i, 10)) html = self.dataGet(i*25) data = self.dataClean(html) self.sqlSave(data) print("爬取成功!") self.conn.close() if __name__ == '__main__': douban = DouBan(user=你的数据库用户名, password=密码) douban.run()

通常,user 是 root,密码是自己设的。如果您未安装 mysql ,请先安装,开启数据库。


四、结尾

喜欢的话,点个关注吧~

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/786644.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号