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

豆瓣电影:TOP250榜单爬虫

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

豆瓣电影:TOP250榜单爬虫

豆瓣电影 Top 250 (douban.com)
#导包
import requests
from bs4 import BeautifulSoup
import pandas as pd
第一步:下载所有页面(共10个)的HTML 【1】构造分页数字列表page_indexs 【2】构造函数download_all_htmls,下载列表所有页面的HTML

1、先添加请求头headers(爬取的网站有反爬虫机制,要向服务器发出爬虫请求,需要添加请求头headers。不然响应状态是418,正常情况应该是200。)

2、利用for循环取到页面列表中的每一个页面的网址url

3、用requests.get函数获取html网页(构造一个向服务器请求资源的url对象,并添加headers参数。返回的是一个包含服务器资源的Response对象。)

4、r.status_code返回http请求的返回状态:200表示连接成功,返回418表示爬取的网站有反爬虫机制,要向服务器发出爬虫请求,需要添加请求头headers

5、htmls.append(r.text)添加每个url对应的页面内容到列表htmls

text()方法:返回文本内容

第二步:解析HTML得到数据 【1】构造函数parse_single_html,用于解析单个html得到数据 1、找到每部电影:

find()方法:只返回第一个匹配到的对象

find(name, attrs, recursive, text, **wargs) # recursive 递归的,循环的

find_all()方法:返回所有匹配到的结果

find_all(name, attrs, recursive, text, limit, **kwargs)   

此处形参用class_的原因:

参考:(13条消息) BeautifulSoup中find和find_all的使用_OCISLU的博客-CSDN博客

soup.find("div",class_="article").find("ol",class_="grid_view").find_all("div",class_="item")
2、用for循环对每部电影取相应类型的数据:

get_text()方法:获取文本内容

#排名
rank=article_item.find("div",class_="pic").find("em").get_text()
#电影名称
title=info.find("div",class_="hd").find("span",class_="title").get_text() 
stars=(
           info.find("div",class_="bd")
               .find("div",class_="star")
               .find_all("span")            #stars里含有4个span,返回一个列表
        )
 #5星评分
rating_star=stars[0]["class"][0]  #第一个span中的class属性的第一个值
 #10分评分  
rating_num=stars[1].get_text()   
 #评论人数
comments=stars[3].get_text()    
3、将每部电影的信息存到字典中,并作为列表的一个元素添加到datas列表中去

字符串替换replace()方法:

datas.append({
            "排名":rank,
            "电影名":title,
            "5星评价":rating_star.replace("rating","").replace("-t",""),
            "10分评分":rating_num,
            "评价人数":comments.replace("人评价","")
        })
【2】执行所有HTML页面的解析
#对每一个HTML页面进行解析,并将结果添加到列表all_datas
all_datas=[]
for html in htmls:
    all_datas.extend(parse_single_html(html))
第三步:将结果存入Excel
df=pd.Dataframe(all_datas)
df.to_excel("豆瓣top250电影榜单.xlsx")
第四步:Dataframe数据导入MySQL
import sqlalchemy
from sqlalchemy import create_engine

#建立连接
conn = create_engine('mysql+pymysql://root:123@localhost:3306/crawl?charset=utf8')
#写入数据,‘replace’表示如果同名表存在就替换掉
df.to_sql(name='douban', con=conn,if_exists='replace',index=False,index_label='排名',
         dtype={'排名': sqlalchemy.types.BigInteger(),
       '电影名': sqlalchemy.types.String(length=20),
       '5星评价': sqlalchemy.types.BigInteger(),
       '10分评分':  sqlalchemy.types.BigInteger(),
       '评价人数':  sqlalchemy.types.BigInteger(),
       })
【完整代码】
import requests
from bs4 import BeautifulSoup
import pandas as pd

page_indexs=range(0,250,25)

def download_all_htmls():
    #先添加请求头headers
    headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Edg/94.0.992.38'}
    htmls=[]    #存放各个url对应的页面内容
    for idx in page_indexs:
        url=f"https://movie.douban.com/top250?start={idx}&filter="
        print("crawl html:",url)   #url是通过http协议存取资源的一个路径,它就像我们电脑里面的一个文件的路径一样
        r=requests.get(url,headers = headers)   #获取html网页(构造一个向服务器请求资源的url对象),并添加headers参数。r返回的是一个包含服务器资源的Response对象,包含从服务器返回的所有相关资源。
        if r.status_code!=200:         # r.status_code 返回http请求的返回状态(200表示连接成功)
            raise Exception("error")   # 返回418表示:爬取的网站有反爬虫机制,要向服务器发出爬虫请求,需要添加请求头headers
        #print(r.status_code)
        htmls.append(r.text)   # r.text 获取url对应的页面内容
    return htmls

htmls=download_all_htmls()

def parse_single_html(html):
    soup=BeautifulSoup(html,'html.parser')    #构建BeautifulSoup实例(第一个参数是要匹配的内容;第二个参数是要采用的模块,即规则)
    article_items=(                         #返回一个列表,代表每个article的信息
       soup.find("div",class_="article")    # find() 只返回第一个匹配到的对象
           .find("ol",class_="grid_view")
           .find_all("div",class_="item")   # find_all() 返回所有匹配到的结果(此处返回所有电影)
    )
    datas=[]   #将数据存到列表里面
    for article_item in article_items:
        rank=article_item.find("div",class_="pic").find("em").get_text()  #获取排名
        info=article_item.find("div",class_="info")
        title=info.find("div",class_="hd").find("span",class_="title").get_text()   #获取电影名称
        stars=(
           info.find("div",class_="bd")
               .find("div",class_="star")
               .find_all("span")            #stars里含有4个span
        )
        #print(stars)
        rating_star=stars[0]["class"][0]    #获取5星评分
        rating_num=stars[1].get_text()     #获取10分评分
        comments=stars[3].get_text()    #获取评论人数
        datas.append({
            "排名":rank,
            "电影名":title,
            "5星评价":rating_star.replace("rating","").replace("-t",""),
            "10分评分":rating_num,
            "评价人数":comments.replace("人评价","")
        })
    return datas

all_datas=[]
for html in htmls:
    all_datas.extend(parse_single_html(html))

df=pd.Dataframe(all_datas)

import sqlalchemy
from sqlalchemy import create_engine
#建立连接
conn = create_engine('mysql+pymysql://root:123@localhost:3306/crawl?charset=utf8')
#写入数据,t_stock_trade_date为数据库表名,‘replace’表示如果同名表存在就替换掉
df.to_sql(name='douban', con=conn,if_exists='replace',index=False,index_label='排名',
         dtype={'排名': sqlalchemy.types.BigInteger(),
       '电影名': sqlalchemy.types.String(length=20),
       '5星评价': sqlalchemy.types.BigInteger(),
       '10分评分':  sqlalchemy.types.BigInteger(),
       '评价人数':  sqlalchemy.types.BigInteger(),
       })
print('ok')

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

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

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