简单的python爬虫——豆瓣

# -*- codeing = utf-8 -*-
# @Time : 2021/8/11 18:50
# Author: hui
# @File : demo.py
# @Software : PyCharm

from bs4 import BeautifulSoup  #网页解析,获取数据
import re  #正则表达式,进行文字匹配
import urllib.error,urllib.request  #指定URL,获取网页数据
import xlwt  #进行Excel操作
import sqlite3  #进行sqlite3数据库操作

# 1、(爬取)获取网页数据
# 2、解析网页数据
# 3、存储数据
def main():
    baseurl="https://movie.douban.com/top250?start="
    #(爬取)获取网页数据
    dataList=getData(baseurl)
    # excel表存储数据
    # savepath="豆瓣电影top10.xls"
    # saveData(dataList,savepath)
    #sqlite3数据库存储数据
    dbpath="movie250.db"
    saveData2db(dataList,dbpath)




#详细页面链接
findLink=re.compile(r'<a href="(.*?)">')# 指定findLink查找字符串规则
#电影名称
findName=re.compile(r'<span class="title">(.*)</span>')
#电影图片
findIMGSrc=re.compile(r'<img.*src="(.*?)"',re.S)  #r为了避免转义字符,re.S忽略换行符
#评分
findRating=re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
#评价人数
findNum=re.compile(r'<span>(\d*)人评价</span>')
#体会
findFeel=re.compile(r'<span class="inq">(.*?)</span>')
#影片的相关内容
findBD=re.compile(r'<p class="">(.*?)</p>',re.S)




#边爬取数据边解析
def getData(baseurl):
    dataList=[]
    for i in range(0,10):     #调用获取页面函数10次
        url=baseurl+str(i*25)
        html=askURL(url)      #将获取内容返回到html中

        #逐一解析数据
        soup=BeautifulSoup(html,"html.parser")  #使用BeautifulSoup中html.parser解析器来解析html中的内容,并保存在soup中
        for item in soup.find_all('div',class_="item"):#以列表的形式查看soup中div下class属性=item的所有内容
            data=[]         #用于保存解析的数据
            item=str(item)     #将item中的信息转化为字符串格式

            #查找电影详细信息的链接
            link=re.findall(findLink,item)[0]   #采用正则表达式查找item中符合findLink规则的所有字符串并返回第一个存在link中
            data.append(link)   #将链接添加到data列表中

            img = re.findall(findIMGSrc, item)[0]
            data.append(img)

            #查找电影姓名
            title=re.findall(findName,item)
            if len(title)==2:         #存在中英文名,如果名字等于2,则分别存储
                ctitle=title[0]        #中文名为title【0】,存在ctitle中
                data.append(ctitle)
                otitle=title[1].replace("/","")     #英文名为title[1],存在otitle中并将英文名前的/用空代替
                data.append(otitle)
            else:                          #如果不存在英文名,直接保存title[0],并在title[1]的位置留空
                data.append(title[0])
                data.append("   ")        #留空

            rating= re.findall(findRating, item)[0]
            data.append(rating)

            num = re.findall(findNum, item)[0]
            data.append(num)

            feel = re.findall(findFeel, item)
            if len(feel) !=0:
                feel=feel[0].replace("。","")
                data.append(feel)
            else:
                data.append("   ")

            base = re.findall(findBD, item)[0]        #规划格式
            base=re.sub("<br(/s+)?/>","  ",base)        #将base中所有<br/>用空代替
            base=re.sub("/"," ",base)                   #将base中所有/用空代替
            data.append(base.strip())                   #strip()去掉base中的空格
            dataList.append(data)           #将每一个电影信息形成一个列表,加入dataList列表中
    return dataList


#excel存储数据
# def saveData(dataList,savepath):
#     book = xlwt.Workbook(encoding="utf-8")
#     sheet = book.add_sheet('豆瓣电影top250')
#     col=("电影链接",'图片链接','电影中文名称','英文名','评分','评分人数','电影概述','相关信息')
#     for i in range (0,8):
#         sheet.write(0,i,col[i])
#     for i in range (0,250):
#         print("第%d个"%(i+1))
#         data=dataList[i]
#         for j in range(0,8):
#             sheet.write(i+1,j,data[j])
#     book.save(savepath)


#sqlite3存储数据


def saveData2db(dataList,dbpath):
    init_db(dbpath)                 #初始化数据库
    conn = sqlite3.connect(dbpath)
    cur = conn.cursor()
    for data in dataList:           #一个data为一条数据
        for i in range(len(data)):       #一个i为data的一列
            if i == 4 or i == 5:
                continue
            data[i] = '"'+data[i]+'"'      #字符链接,每个字符前后加上引号(双引号)
        sql = '''
        insert into movie250 (           /*存在缩进问题,保持书写格式*/
        info_link,pic_link,cname,oname,score,people,feel,near)
        values (%s)''' % ",".join(data)       #是占位的数据,并将data中的数据用逗号连接(用双引号包围逗号)
        cur.execute(sql)
        conn.commit()
    cur.close()
    conn.close()



#初始化数据库
def init_db (dbpath):
    sql='''
        create table movie250
        (
        id integer primary key autoincrement,
        info_link text,
        pic_link text,
        cname varchar ,
        oname varchar ,
        score numeric ,/*显示小数*/
        people number ,
        feel text,
        near text
        );
    
    '''
    conn=sqlite3.connect(dbpath)      #连接数据库创建名为dbpath的数据库,存在则打开,不存在则创建
    curson=conn.cursor()               #获得游标,方便后续操作
    curson.execute(sql)                #执行sql语句
    conn.commit()                      #提交数据库操作
    conn.close()                       #关闭数据库


#获取指定URL页面的内容
def askURL(url):
    header={
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36 SLBrowser/7.0.0.6241 SLBChan/32"
    }
    request=urllib.request.Request(url,headers=header)
    html = ""
    try:
        response=urllib.request.urlopen(request)
        html=response.read().decode("utf-8")
        #print(html)
    except Exception as e:
        if hasattr(e,"code"):
            print(e.code)
        if hasattr(e,"reason"):
            print(e.reason)
    return html



if __name__=="__main__":
    main()
    print("爬取结束")