Python爬虫实战:爬取日漫新番数据

1.前言

        日本动漫凭着剧情的创新和趣味性在全球占有着重要地位,一般日漫新番播出的时间在一、四、七、十这四个月份上面。

        正处于2021年年末,大家大多都对即将开播的一月新番还不了解,本次爬虫实战则是爬取一月新番数据,在本次实战中,yuc.wiki网站中对动漫的数据整理比较齐全,所以博主选择了yuc.wiki进行新番数据爬取。

        在本次实验中,所得数据仅进行学习交流使用,建议大家合理使用爬虫。

1.1流程介绍

        导入库->爬取网站->在爬取网站的过程中逐一解析数据->数据保存->数据分析->数据的可视化,在本次中,数据的可视化通过flask,对数据进行html的展示

def main():
    baseurl = "https://yuc.wiki/202201/"
    #1.爬取网页  2.在爬取数据过程中逐一解析数据
    datalist = getData(baseurl)
    dbpath = "anime_1month.db"
    #3.保存数据
    saveData(datalist,dbpath)


#创建正则表达式



#爬取网页与逐一解析数据
def getData(baseurl):



#得到一个网页的数据
def askURL(url):


#保存数据
def saveData(datalist,dbpath):


def init_db(dbpath):




if __name__ == "__main__":
    main()
    print("爬取完毕!")
#数据的可视化
from flask import Flask,render_template
import sqlite3




app = Flask(__name__)




@app.route('/')
def index():





if __name__ == '__main__':
    app.run()

2.数据爬取

2.1对网页获取基本的信息

打开需要爬取的网页,按F12,点击网络(不同浏览器中,按F12后可能布局不太一样,此处以火狐浏览器为例),

 对网页进行刷新操作,点击左侧任意栏,找到右侧的user-agent一栏对其复制(注意去除其中的空格)

Python爬虫实战:爬取日漫新番数据_第1张图片

 2.2对爬虫进行伪装

def askURL(url):
    head = {
        "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.43"
    }#模拟头部,进行伪装
#此处User-Agent的内容为前一步中复制的内容
    request = urllib.request.Request(url,headers=head)
    html = ""
    try:
        response = urllib.request.urlopen(request)
        html = response.read().decode("utf-8")
        #print(html)
    except urllib.error.URLError as e:
        if hasattr(e,"code"):
            print(e.code)
        if hasattr(e,"reason"):
            print(e.reason)
    return html

2.3正则表达式

在本次中,因为网站中对同一类数据使用了多种标签,因此此处正则表达式较多。正则表达式可以对爬取到的数据进行信息匹配、筛选,在处理后则会得到自己想要的数据信息。标签的信息可以在网页中按F12->查看器,即可看到自己想要爬取的数据的标签。

#创建正则表达式,表示规则
#片名
findNameA = re.compile(r'

(.*)

') findNameB = re.compile(r'

(.*)

') findNameC = re.compile(r'

(.*)

') # PV链接 findPVLink = re.compile(r'a.*href="(.*)" target="_blank">PV',re.S)#re.S表示忽略其中的换行符 #播放时间 findTime = re.compile(r'

(.*?)

') #番剧性质 findTypeA = re.compile(r'(.*)') #原创动画 findTypeB = re.compile(r'(.*)') #漫画改编 findTypeBB = re.compile(r'(.*)') findTypeBBB = re.compile(r'(.*)') findTypeC = re.compile(r'(.*)') #小说改编 findTypeCC = re.compile(r'(.*)') findTypeD = re.compile(r'(.*)') #游戏改编 findTypeE = re.compile(r'(.*)') #其他题材 #番剧类型(标签) findBQA = re.compile(r'(.*)') findBQB = re.compile(r'(.*)')

2.4爬取网页并逐一解析数据

def getData(baseurl):
    datalist = []
    url = baseurl
    html = askURL(url)#保存获取的网页源码

    # 2.逐一解析数据
    soup = BeautifulSoup(html,"html.parser")
    for tbody in soup.find_all('table',width="500px"):#查找符合要求的字符串,行形成列表
        #print(tbody)  #对爬取的一个番剧的信息进行输出测试
        data = []  #保存一个番剧的所有信息
        tbody = str(tbody)
        NameA = re.findall(findNameA,tbody)  #re库来通过正则表达式查找指定字符串
        if len(NameA) == 0:
            NameB = re.findall(findNameB,tbody)
            if len(NameB) == 0:
                NameC = re.findall(findNameC,tbody)
                Name = ''.join(NameC)
                Name = re.sub(' ', "", str(Name))
                data.append(Name)
            else:
                Name = ''.join(NameB)
                Name = re.sub(' ', "", str(Name))
                data.append(Name)#片名
        else:
            Name = ''.join(NameA)
            Name = re.sub(' ', "", str(Name))
            data.append(Name)
        # print(Name)
        TypeA = re.findall(findTypeA, tbody)
        if len(TypeA) == 0:
            TypeB = re.findall(findTypeB,tbody)
            if len(TypeB) == 0:
                TypeC = re.findall(findTypeC, tbody)
                if len(TypeC) == 0:
                    TypeD = re.findall(findTypeD,tbody)
                    if len(TypeD) == 0:
                        TypeBB = re.findall(findTypeBB, tbody)
                        if len(TypeBB) == 0:
                            TypeBBB = re.findall(findTypeBBB, tbody)
                            if len(TypeBBB) == 0:
                                TypeCC = re.findall(findTypeCC, tbody)
                                if len(TypeCC) == 0:
                                        TypeE = re.findall(findTypeE,tbody)
                                        Type = ''.join(TypeE)
                                        Type = re.sub('
',"",str(Type)) data.append(str(Type)) else: Type = ''.join(TypeCC) data.append(str(Type)) else: Type = ''.join(TypeBBB) data.append(str(Type)) else: Type = ''.join(TypeBB) data.append(str(Type)) else: Type = ''.join(TypeD) data.append(str(Type)) else: Type = ''.join(TypeC) data.append(str(Type)) else: Type = ''.join(TypeB) data.append(str(Type)) else: Type = ''.join(TypeA) data.append(str(Type))#性质 BQA = re.findall(findBQA,tbody) if len(BQA) == 0: BQB = re.findall(findBQB, tbody) BQS = ''.join(BQB) BQS = re.sub('/', " ", str(Type)) data.append(str(BQS))#标签 else: BQS = ''.join(BQA) BQS = re.sub('
', "", str(BQS)) BQS = re.sub('/', " ", str(BQS)) data.append(str(BQS)) Time = re.findall(findTime,tbody)[0] if Time != '': if Time != '': Time = re.sub('/', ".", str(Time)) data.append(Time) else: data.append('暂无播放时间') # 播放时间 else: data.append('暂无播放时间') PVLink = re.findall(findPVLink,tbody) if len(PVLink) != 0: PVLink = ''.join(PVLink) data.append(str(PVLink))#PV播放链接 else: data.append("") #留空 datalist.append(data) #把一部番剧数据放入datalist #print(datalist) #输出测试 return datalist

3.数据存储

3.1数据库(表)建立

在数据进行存储前,我们先创建表,此处为定义函数创建表的内容

def init_db(dbpath):
    sql = '''
        create table anime_1month
        (
        id integer primary key autoincrement,
        anime_name varchar,
        anime_type varchar,
        anime_bq varchar,
        anime_time varchar,
        anime_link varchar
        )
    '''#创建数据库

    conn = sqlite3.connect(dbpath)
    cursor = conn.cursor()
    cursor.execute(sql)
    conn.commit()
    conn.close()

3.2数据存储

#保存数据
def saveData(datalist,dbpath):
    init_db(dbpath)#此处进行前面的创建过程
    conn = sqlite3.connect(dbpath)
    cur = conn.cursor()

    for data in datalist:
        for index in range(len(data)):
            data[index] = '"'+data[index]+'"'
        sql = '''insert into anime_1month(
            anime_name,anime_type,anime_bq,anime_time,anime_link)
            values(%s)'''%",".join(data)
        print(sql)
        cur.execute(sql)
        conn.commit()
    cur.close()
    conn.close()

在存储后可打开数据库进行数据的查看

Python爬虫实战:爬取日漫新番数据_第2张图片

共计41条数据,数据无误。

4.数据分析与可视化

4.1数据分析

通过爬取的41条信息,我们可以分析到,新番类型是漫画改编最多,这也说明了目前日本主流仍旧是漫画进行动漫化,对于日本的动漫产业,漫画具有一定的基础粉丝,进行动漫化的具有更高的收益价值并且风险较低。

4.2可视化

在本次数据可视化中利用了在网上下载的现成CSS样式,可在模板之家等网站中下载。

新建一个flask项目

from flask import Flask,render_template
import sqlite3

app = Flask(__name__)


@app.route('/')
def index():  # put application's code here
    datalist = []
    con = sqlite3.connect("anime_1month.db")
    cur = con.cursor()
    sql = "select * from movie41"
    data = cur.execute(sql)
    for item in data:
        datalist.append(item)
    cur.close()
    con.close()
    return render_template("index.html",movies = datalist)

if __name__ == '__main__':
    app.run()

在下载的模板中打开index.html文件,删除部分不需要的元素,并对其中的图片进行替换,对部分文字进行修改

代码中仅展示在网页中新添加的内容

                        
                            {% for movie in movies %}
                                
                            {% endfor %}


                            
序号 动漫名 类型 标签 播放时间
{{movie[0]}} {{ movie[1] }} {{movie[2]}} {{movie[3]}} {{movie[4]}}

网页截图1:此部分截图为修改html中的文字和图片实现

网页截图2:

同时对动漫名做了超链接,点击名字可以直接跳转到相应的PV链接网站 ,此处截图的代码为新添加内容

Python爬虫实战:爬取日漫新番数据_第3张图片

你可能感兴趣的:(python,爬虫,数据挖掘)