(转)Python3爬取豆瓣电影保存到

发布时间:2019-10-16 17:29:11编辑:auto阅读(1792)

    48行代码实现Python3爬取豆瓣电影排行榜
    代码基于python3,用到的类库有:

    标题文字

    requests:通过伪造请求头或设置代理等方式获取页面内容,参考文档
    BeautifulSoup:对页面进行解析,提取数据,参考文档
    PyMySQL:python3版本中用于操作MySQL数据库,python2中则使用mysqldb,Github

    pip安装用到的几个类库:

    pip install requests
    pip install bs4
    pip install pymysql
    分析豆瓣电影页面
    页面分析:
    爬取数据之前,我们都需要对页面进行分析,看我们可以从中提取到哪些数据,从下图我们看到豆瓣电影top250的页面结构,我们可以从中提取出排行榜(rank)、电影名字(name)、电影详情页链接(link)、电影海报(poster)、电影评分(score)、电影评论(quote)等,我在图中进行了标注

    URL分析:
    通过点击分页我们可以发现URL的格式为:https://movie.douban.com/top2...
    其中num表示25的倍数的数字,最小是0也就是第一页,最大为225也就是最后一页,这可以作为我们爬取页面的限制条件,filter为过滤条件这里可不用管

    代码
    引入类库:

    import pymysql
    import requests
    from bs4 import BeautifulSoup
    定义爬取链接,%d用作数字占位:

    baseUrl = "https://movie.douban.com/top250?start=%d&filter="
    定义爬取数据方法:

    def get_movies(start):

    url = baseUrl % start   # 拼接爬取链接
    lists = []              # 存储此页面的电影数据
    html = requests.get(url)    # requests请求页面内容,由于豆瓣没有限制爬取,所以不用设置伪请求头
    soup = BeautifulSoup(html.content, "html.parser")   # BeautifulSoup解析页面内容
    items = soup.find("ol", "grid_view").find_all("li") # 获取所有的电影内容
    for i in items:
        movie = {}      # 临时存取电影的数据
        movie["rank"] = i.find("em").text   # 电影排行榜
        movie["link"] = i.find("div","pic").find("a").get("href")   # 电影详情页链接
        movie["poster"] = i.find("div","pic").find("a").find('img').get("src")  # 电影海报地址
        movie["name"] = i.find("span", "title").text    # 电影名字
        movie["score"] = i.find("span", "rating_num").text  # 电影评分
        movie["quote"] = i.find("span", "inq").text if(i.find("span", "inq")) else "" # 某些电影没有点评,没有就设为空
        lists.append(movie) # 保存到返回数组中
    return lists

    连接数据库并创建数据表:

    连接数据库,需指定charset否则可能会报错

    db = pymysql.connect(host="localhost",user="root",password="root",db="test",charset="utf8mb4")
    cursor = db.cursor() # 创建一个游标对象
    cursor.execute("DROP TABLE IF EXISTS movies") # 如果表存在则删除

    创建表sql语句

    createTab = """CREATE TABLE movies(

    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(20) NOT NULL,
    rank VARCHAR(4) NOT NULL,
    link VARCHAR(50) NOT NULL,
    poster VARCHAR(100) NOT NULL,
    score VARCHAR(4) NOT NULL,
    quote VARCHAR(50)

    )"""
    cursor.execute(createTab) # 执行创建数据表操作
    ......
    db.close() # 关闭数据库
    将提取到的数据存储到数据表中:

    lists = get_movies(start) # 获取提取到数据

    for i in lists:
        # 插入数据到数据库sql语句,%s用作字符串占位
        sql = "INSERT INTO `movies`(`name`,`rank`,`link`,`poster`,`score`,`quote`) VALUES(%s,%s,%s,%s,%s,%s)"
        try:
            cursor.execute(sql, (i["name"], i["rank"], i["link"], i["poster"], i["score"], i["quote"]))
            db.commit()
            print(i[0]+" is success")
        except:
            db.rollback()
    start += 25

    完整代码:

    import pymysql
    import requests
    from bs4 import BeautifulSoup
    baseUrl = "https://movie.douban.com/top250?start=%d&filter="
    def get_movies(start):

    url = baseUrl % start
    lists = []
    html = requests.get(url)
    soup = BeautifulSoup(html.content, "html.parser")
    items = soup.find("ol", "grid_view").find_all("li")
    for i in items:
        movie = {}
        movie["rank"] = i.find("em").text
        movie["link"] = i.find("div","pic").find("a").get("href")
        movie["poster"] = i.find("div","pic").find("a").find('img').get("src")
        movie["name"] = i.find("span", "title").text
        movie["score"] = i.find("span", "rating_num").text
        movie["quote"] = i.find("span", "inq").text if(i.find("span", "inq")) else ""
        lists.append(movie)
    return lists
    

    if name == "__main__":

    db = pymysql.connect(host="localhost",user="root",password="root",db="test",charset="utf8mb4")

关键字