互动
最近评论

数据分析

源码页面:https://halo.suzakudry.top/yuan-ma-dang-an

源码github: https://github.com/FCYXSZY/-

Pixiv插画作品元素流行趋势分析·1

本项目主要目的为爬取Pixiv的的图片相关信息,进行数据分析。

(例如点赞、收藏、浏览量等)

同时添加了自定义 评分 = 0.3\*点赞量+0.5\*收藏量+0.2\*浏览量

项目地址:

项目框架

pixiv-
├── flask2
│   ├── app.py web框架
│   ├── DAO.py 数据库交互层
│   ├── reptile.py 爬虫
│   ├── dataSql.DB 数据库存储爬取的信息
│   ├── static 存储html静态资源
│   └── templates 存储html模板
├── config  配置文件COOkie和UA模拟浏览器登录,和数据库地址
├── output 存储爬取的图片
├── README.md 项目说明
└── requirements.txt 项目依赖,自动创建虚拟环境

项目使用到的工具

  • SQLite 轻量内嵌式数据库。存储数据也可以用Excel

  • lxml 解析html网页(解析request的response.text),c语言实现速度较快。流程:->解析:lxml.etree->提取:html.xpath

  • pandas 数据

  • requests 网络请求(requests简明介绍

  • selenium 模拟浏览器

  • pyecharts 数据可视化绘图 (数据可视化也可以用matplotlib,但由于我是部署到网页web端上了,而pyecharts 生成的图表是 HTML + JavaScript 格式,可以直接嵌入网页中,且具有交互性。而matplotlib生成的一般是图片格式的静态表格效果不太好。)

  • flask web框架(简单应用:halo.suzakudry.top/archives/flaskjian-dan-shi-yong

  • Jinja2 模板引擎用于生成网页(不怎么会用)

  • tqdm 过程可视化(拒绝枯燥的等待时间)

运行环境

  • python3.9

  • windows11

答辩内容

Part1.数据收集

- 爬取内容:

爬取内容主要包括Pixiv网站上的艺术作品信息,包括作品的标题、作者、图片链接、浏览量、点赞数、收藏数以及标签等。

即图中数据库类型的内容。

- 爬取方法:

  1. 爬虫相关:
    使用selenium(通过web_driver自动化web测试)爬取。
    后改用selenium+requests的方式,先用自动化爬取要下载的具有反爬虫规则的图片链接,并在此阶段收集网站图片的信息:标签作者浏览量等

    后通过requests下载二进制数据的图片。

    实现:
    先通过沿着插画排行榜页面爬取每个作品的id信息。
    通过requests 得到网页的HTML 页面源代码(字符串格式),
    在通过lxml库中的模块etree的etree.HTML(context)解析成一个可供操作的树形结构,
    然后可以通过Xpath、ID、类名、CSS选择器等方法提取信息。(Xpath基本语法
    提取id后,拼接成每个作品的链接(f'https://www.pixiv.net/artworks/{作品id}')。

    def get_NewPage(url):
        if url == "":
            url = "https://www.pixiv.net/ranking.php?mode=daily&content=illust"
        print(url)
        context = requests.get(url = url,headers=headers,proxies=proxies).text
        html = etree.HTML(context)
        print('finished get')
        nowtime = html.xpath('//*[@id="wrapper"]/div[1]/div/div[2]/div/nav[2]/ul/li[2]/a/text()')[0] # 获取当前排名的日期----nowtime
        print(nowtime.encode("utf-8").decode("utf-8"))
        o = html.xpath('/html/body/div[3]/div[1]/div/div[3]/div[1]/section/div[2]/a[1]/@href')
        o = [up_url+x for x in o if "user" not in x] # 各个作品的网页
        return o,nowtime,html


    然后应该是通过自动化进入每个作品的页面爬取信息,
    但发现原始的图片链接具有反爬虫规则,
    不登录,或者不点击缩略图进入大图模式,连链接都获取不到……
    所以需要配置cookie模拟用户登录,如下:

    # 获取Cookie并加载到Selenium中
    def getCookie(driver):
        driver.get("https://www.pixiv.net/")
        time.sleep(60)
        print(driver.get_cookies())
        with open('cookies.txt', 'w') as f:
            f.write(json.dumps(driver.get_cookies()))
    def login(driver):
        driver.get("https://www.pixiv.net/")
        with open('cookies.txt', 'r') as f:
            cookies_list = json.load(f)
            for cookie in cookies_list:
                # 检查并转换Cookie中的expiry字段
                if isinstance(cookie.get('expiry'), float):
                    cookie['expiry'] = int(cookie['expiry'])
                driver.add_cookie(cookie)
        driver.refresh()


    登录完成。
    现在通过自动化进入每个作品的页面爬取信息,使用selenium的find_element方法,通过Xpath、ID、类名、CSS选择器等获取数据。(此处获取到作品的标题、作者、图片链接、浏览量、点赞数、收藏数以及标签等)

    def getDataFromWeb(url, nowTime):
        global browser, download_num
        browser.get(url)
        taget = [a.text for a in browser.find_elements(By.CLASS_NAME,'gtm-new-work-tag-event-click')]
    
        temp = [b.text for b in [a.find_element(By.TAG_NAME,'dd') for a in
                                 browser.find_element(By.CLASS_NAME,'dpDffd').find_elements(By.TAG_NAME,'li')]]
    
        writer = browser.find_element(By.CLASS_NAME,'fATptn').find_element(By.TAG_NAME,'div').text
        imgurl = ''
        if download_num > 0:
            try:
                image_element = browser.find_element(By.CSS_SELECTOR, "img.sc-1qpw8k9-1")
                parent_a_element = image_element.find_element(By.XPATH, "..")
                image_url = parent_a_element.get_attribute("href")
                #image_url = image_element.get_attribute("href")
                # url_match=ret_match(image_url)
                # original_image_url = extract_and_build_pixiv_url(url_match)
                # imgurl = url_match
                original_image_url= [image_url]
                imgurl = image_url
                print(f"Image URL: {imgurl}")
                if(download_num==1): pass
                else:
                    download_list.extend(original_image_url)
                    download_num -= 1
    
            except Exception as e:
                print('不许看哦')
                pass
                #print(f"Error while downloading image: {e}")
    
        return [nowTime, writer, temp[0], temp[1], temp[2], taget, imgurl]
    


    获取的数据先存储到list里,

    def thread_getData(url_list,nowTime):
        for url in tqdm(url_list, desc="获取数据进度", ncols=100, unit="项"):  # 使用 tqdm 包装 url_list
            print('--'+url)
            data_list.append(getDataFromWeb(url,nowTime))


    最后通过df的构造函数转为df数据,打上标签通过DAO(数据交互层),使用df的to_sql方法,将数据导入数据库,实现数据可持久化。
    (坑点:国外网站数字会以这种形式1,000,000,所以先去掉顿号",",然后再转成数字类型)

    data = pd.DataFrame(data_list)
    data.columns = ['日期', '作者', '点赞', '收藏', '浏览', '类型', '图片url']
    data['点赞'] = data['点赞'].str.replace(',', '')
    data[['点赞']] = data[['点赞']].astype('int')
    data['收藏'] = data['收藏'].str.replace(',', '')
    data[['收藏']] = data[['收藏']].astype('int')
    data['浏览'] = data['浏览'].str.replace(',', '')
    data[['浏览']] = data[['浏览']].astype('int')
    data['日期'] = data['日期'].astype('string')
    data['作者'] = data['作者'].astype('string')
    data['类型'] = data['类型'].astype('string')
    data['评分'] = round(data.点赞 * 0.3 + data.收藏 * 0.5 + data.浏览 * 0.2,2)
    data['图片url'] = data['图片url'].astype('string')
    DAO.insert(data)



图片的爬取
上述使用了selenium爬取作品的一系列特征信息,但并没有实现爬取图片。(因为并不会)
以下再次使用requests实现图片下载。
首先,因为是国外网站,要配置代理。使用selenium时设置代理比较简单
browser_options.add_argument("--proxy-server=" + proxy)


但是在使用request是发现直接使用这样的代码配置后传入,会出现proxyERROR

错误代码:
proxy = {
   "http": "http://127.0.0.1:7890",
   "https": "https://127.0.0.1:7890"
   "socks":'socks5://127.0.0.1:7890'
}
………………
requests.get(url, headers=headers, proxies=proxy)
报错:proxyERROR

httphttps 的代理协议(详解http和https)
即使目标网址使用 HTTPS 协议,是代理服务器和目标服务器的传输,而客户端与代理服务器仍然通常使用 HTTP 协议 作为传输方式。因此,代理 URL 应写成 http:// 而不是 https://

#正确配置
proxies = {
    "http": "http://127.0.0.1:7890",
    "https": "http://127.0.0.1:7890",
    "socks":'socks5://127.0.0.1:7890'
}

之后是设置header,用来伪装浏览器请求。

headers = {
    "Cookie": Cookie ,
    "User-Agent": 模拟浏览器标识
}

准备到这。下载原图还是下不下来了,因为pixiv还有一重防盗链保护"referer" ,这里不细讲了,感兴趣可以去我博客看。

链接:referer防盗链

总之突破了反爬机制后。直接通过以下代码保存到本地即可 。

#直接 response = requests.get ()然后.content()获取图片二进制数据(或者.iter_content()分块获取)
response = requests.get(url, headers=headers, proxies=proxy_config.proxy)
sleep(0.5)
#(细节,请求完time.sleep(几秒)一下,不然由于请求频繁,服务器会强制关闭连接。 ConnectionResetError 别问我怎么知道的)
if response.status_code == 200:
      #分快下载优点
      #支持断点续传(已经写入的数据仍然安全地存储在文件中)直接调用write当出现网络波动会直接下载失败。
      #降低内存占用
      #wb 只写方式打开或新建一个二进制文件,只允许写数据。  
      with open(save_path, 'wb') as f:
         for chunk in response.iter_content(1024):  # 分块写入文件
             f.write(chunk)

常见的简单反爬突破方法还有 通过User-Agent来控制访问 IP代理池 模拟浏览器行为 等等

(更多细节见github,或我的博客

2, 数据处理

首先确认下已有的信息:包括作品的原图,标题、作者、图片链接、浏览量、点赞数、收藏数以及标签等。

通过数据处理库,进行数据分析和解读,提取有价值的信息。

先明确该清洗掉哪些信息,标签,哪些是无用的?

此处定义有用信息。

有用信息的判断标准:

  1. 对分析目标有帮助:

    • 标签“日期”用于流量和评分的时间变化趋势。

    • 标签“自定义评分”是分析作家和作品质量的关键指标。

    • 标签“收藏”用于评估作品热度,筛选出受欢迎的作品。

  2. 对模型训练或可视化有价值:

    • 标签“类型”代表作品内容的主题,可以帮助生成热点标签词云。

最后数据分析大师chatgpt决定需要清洗处理的数据为:

  • 重复数据

  • 空值并填充空值

  • 无用标签

  • 异常值

。。。。。。。。。。。。

数据预处理过程

def pre():
    global data
    sql = "select * from test"
    data = DAO.select_data(sql)
    data = data.drop_duplicates()

    # 删除空值或填充空值
    data = data.dropna(subset=['日期', '评分'])  # 删除“日期”和“评分”为空的行
    data['评分'] = data['评分'].fillna(data['评分'].mean())  # 填充评分的均值

    # 清理无用标签
    data['类型'] = data['类型'].str.replace(r'users入り', '', regex=True)  # 去掉无意义的标签
    data['类型'] = data['类型'].str.replace(r'[^\w\s,]', '', regex=True).str.strip()  # 去掉标点和多余空格

    # 去除异常值(以评分为例)
    q1 = data['评分'].quantile(0.25)
    q3 = data['评分'].quantile(0.75)
    iqr = q3 - q1
    data = data[~((data['评分'] < (q1 - 1.5 * iqr)) | (data['评分'] > (q3 + 1.5 * iqr)))]  # 去掉评分异常值

Part3, 数据分析与可视化

分析数据的特征

数据的维度包括:

  • 作品的浏览量:评估作品的受关注程度。

  • 作品的点赞:反映作品的喜爱程度。

  • 作品的收藏:体现作品的长期价值和用户粘性。

  • 作品的标签 :提取作品的主题或风格特征。

通过多维度的信息,得出作品的综合评分。

通过分配不同的权重得到 综合评分 = 0.3\*点赞量+0.5\*收藏量+0.2\*浏览量

可视化效果:

图片中的艺术作品信息可视化展示。通过图表、图形等方式展示艺术作品的数据信息,让读者更直观地了解作品的受欢迎程度及流行趋势。

  • 折线图:展示数据变化趋势。

  • 柱状图:对比不同作品的表现数据。

  • 时间轴图:分析流行趋势的时间分布。

  • 词云图:呈现作品的热门标签或关键词。

    j可视化图标都是通过pyecharts生成,代码大差不差,展示其中较复杂的词云生成:

def hotWord_base()->WordCloud:
    # 热点标签生成
    label_value = {}

    for i in range(len(data)):
        if data['收藏'][i] >= 1000:
            temp = data['类型'][i].split(',')
            temp = [var.replace('[', '').replace(']', '').replace("'", '').strip() for var in temp]
            temp = [var for var in temp if not var.endswith("users入り")]
            for v in temp:
                if v not in label_value.keys():
                    label_value[v] = 0
                label_value[v] += data['评分'][i]
    label_value = label_value.items()

    # 创建词云图
    c = (
        WordCloud()
        .add(series_name="热点标签", data_pair=label_value, word_size_range=[20, 80])  # 调整字体大小范围
        .set_global_opts(
            title_opts=opts.TitleOpts(
                title="热点标签", title_textstyle_opts=opts.TextStyleOpts(font_size=23)
            ),
            tooltip_opts=opts.TooltipOpts(is_show=True),
        )
        .set_series_opts(
            #设置为菱形
            shape="star",  # 设置为圆形
            word_gap=5,  # 设置词与词之间的间距
            rotation_range=[-90, 90]  # 允许词云旋转
        )
    )

    # 调整图表的宽度和高度(可选,视需要)
    c.width = "100%"  # 设置为100%的宽度,适应屏幕
    c.height = "1050px"  # 设置词云图的高度
    return c

全部实现方法:

用 Flask 框架构建的 Web 应用,使用Jinja2 环境来加载模板并生成最终的 HTML 内容。

主要通过 pyecharts 实现可视化数据。

代码结构中还包含了数据库操作、静态文件的管理,以及通过 waitress 部署服务器。

最后通过docker 将微服务部署到服务器上,提供在线访问。

最后的最后通过通过Nginx将ip地址反向代理到域名上,且隐藏真实ip

不再一一介绍,最后的效果为——

anl.suzakudry.top

且通过热点标签分析,得到以下结论:

pixiv插画网站虽远在日本,但也远受国产游戏米哈游的影响,出现大量米哈游旗下作品(原神等)的同人作品。

…………………………等

同时,通过数据分析,发掘了具有潜力新人画师Mika pikazo,其风格如下。


part4.数据与应用

一,通过收集的图片,训练sd类图片生成式模型,投入实际生产绘图。

二,通过经过筛选的图片,训练ai模型,实现自动筛选符合用户预期的图片。

三,通过已有的标签热度,为作者和用户提供预测作品的流行趋势。

未完待续(并不会机器学习。)



----------to be continued----------

总结(ai生成人工润色)

Pixiv插画作品的流行趋势分析总结

本项目的目标是通过爬取Pixiv网站排行榜的插画作品信息,分析流行趋势,尽可能地描述插画作品在网站上的热度和大众兴趣。


一、数据采集

1. 爬取内容

  • 爬取目标:

    • 作品的标题

    • 作者名称

    • 图片链接

    • 浏览量

    • 点赞数

    • 收藏数

    • 标签

  • 工具实现:

    • Selenium + Requests:模拟浏览器登录。

    • **Referer模拟:**实现正常的HTTP请求,回避403错误。

    • **网络代理配置:**解决国外网站加载慢问题。

    • **文件下载:**分块下载实现、支持断点续传。

  • 最终爬取结果:

    • 插画数据存储在SQLite数据库中,进行处理和分析。

    • 图片存储在output里

2. 触发问题及解决方案

  • **Cookie和Referer模拟:**正确的Referer和Cookie是破解Pixiv反爬机制的关键。

    • **常见问题:**403错误,反爬拦截。

    • 解决方案:

      • 使用正则表达式获取插画ID,并拼接Referer链接。

      • 配置正确的HTTP和HTTPS代理。

  • 模拟浏览器:

    • 通过Selenium实现自动登录与数据爬取,有效解决登录验证与数据加载问题。


二、数据处理

  • 数据清洗:

    • 删除重复数据。

    • 填充空值,确保完整性。

    • 清理无用标签。

    • 移除并处理异常值。

  • 关键数据:

    • **日期标签:**分析作品流量和评分随时间的变化趋势。

    • **评分标签:**衡量作者作品质量的重要指标。

    • **收藏标签:**用于评估作品热度和用户喜爱程度。

    • **类型标签:**用于生成热点词云,识别流行主题。

  • 工具:

    • 使用Pandas进行数据清洗和转换,为分析提供支撑。


三、数据分析

基于以下维度:

  1. 作品浏览量:

    • 监测作品在用户中的曝光度。

    • 分析浏览量的时间分布,识别流行时段。

  2. 点赞数与收藏数:

    • 作品的点赞数和收藏数是流行程度的重要指标。

    • 比较不同标签和类型的作品受欢迎程度。

  3. 标签热度分析:

    • 通过标签词云展示流行的关键词和主题。

    • 识别长期和短期流行标签。

  4. 时间趋势:

    • 分析作品流行趋势的时间变化。

    • 识别哪些作品类型或标签在特定时间段更受欢迎。


四、预测与应用

通过收集和分析的数据,可以实现以下应用:

  1. 评分预测模型:

    • 使用机器学习模型(如线性回归、决策树等)基于标签、浏览量、点赞数等特征预测作品评分。

    • 帮助创作者了解哪些元素更容易提升作品的受欢迎程度。

  2. 流行趋势预测:

    • 通过时间序列分析,预测特定标签或作品类型的未来流行趋势。

    • 提供数据支持,帮助用户把握创作方向。

  3. 作品自动筛选:

    • 基于用户偏好标签,自动筛选符合预期的作品。

    • 提供个性化推荐,提升用户体验。

  4. AI生成画风模拟:

    • 利用爬取的插画图片数据,训练生成式AI模型(如Stable Diffusion)。

    • 模拟画师风格,自动生成符合特定风格的插画作品。


五、总结与展望

本项目通过Pixiv数据的爬取、清洗与分析,实现了对插画作品流行趋势的深入挖掘。未来,通过引入评分预测模型和AI生成技术,可以进一步实现作品流行趋势的预测和个性化推荐,为创作者和用户提供更加智能化的服务。


评论
你无需删除空行,直接评论以获取最佳展示效果
引用到评论