动荡的青春

听风雪在喧嚷,看流星在飞翔;
我心向我呼唤,去动荡的远方。

0%

网络爬虫玩具性实战:公主连结官方壁纸、头像下载

问题定义

今天我们来搞一搞公主连结官方发布的壁纸和头像的爬虫及下载。

公主连结HP:
プリンセスコネクト!Re:Dive (プリコネR) 公式サイト | Cygames

主要涉及的网站:
ファンキット | プリンセスコネクト!Re:Dive (プリコネR) 公式サイト | Cygames

其中的イベント部分为官方发布的所有的活动,包含我们想要的壁纸和头像,因此对此进行爬虫可达到我们目的。

  1. イベント页面

  2. 我们想要下载的壁纸和头像(例:第8856号イベント页面

状况分析

  1. 对于每一个ファンキット页面,我们发现合法的页面的标号是从1开始到无穷的。
    1) 第0页:

    1
    https://priconne-redive.jp/fankit02/page/0/?type=event

    返回与第1页相同的内容,但URL保持不变。不妨跳过第0页的爬虫。

    2) 第1页:

    1
    https://priconne-redive.jp/fankit02/page/1/?type=event

    返回第1页,并且URL自动变为:

    1
    https://priconne-redive.jp/fankit02/?type=event

    但我们可以忽视此URL变化的问题,因为用原URL请求,返回的内容也是没有问题的。

    3) 第2页:

    1
    https://priconne-redive.jp/fankit02/page/2/?type=event

    正常返回第2页内容。

    4) 到2020/06/19时间节点为止一共有2页。从第3页开始:

    1
    https://priconne-redive.jp/fankit02/page/3/?type=event

    虽然正常返回页面,但页面里不存在任何一个イベント页面。如下图:

    这成为我们的爬虫终止条件

  2. 在每一个ファンキット页面里存在多个イベント页面。对于每一个イベント页面,其URL格式均为如下形式:

    1
    https://priconne-redive.jp/fankit02/[0-9]*/

    在此,我们以请求第8856号イベント页面为例(图2
    1) 我们发现其中所有有价值的图片文件的URL前缀均为:

    1
    https://priconne-redive.jp/ele-wp/wp-content/uploads/

    2) 并且,我们设置了如下后续的正则表达式,以确定有价值的JPG或PNG图片名称:

    1
    [0-9]+/[0-9]+/[a-zA-Z0-9]*\.(?:jpg|png)

    3) 最终,核心的正则表达式如下:

    1
    https://priconne-redive.jp/ele-wp/wp-content/uploads/[0-9]+/[0-9]+/[a-zA-Z0-9]*\.(?:jpg|png)

解决流程

  1. 从1向无穷循环
    1) 与基本URL(https://priconne-redive.jp/fankit02/page)拼接递增的页码号,生成各个ファンキット页面URL,并设置type=event进行GET请求,获取HTML内容:

    getResURLs(base_url)
    1
    2
    3
    4
    url = base_url + "/" + str(i)
    params = {'type': 'event'} # https://.../page/1 -> 2/?type=event
    r = requests.get(url, params=params)
    s = r.text

    2) 对返回的HTML内容进行如下正则匹配:

    getResURLs(base_url)
    1
    2
    pattern = "https://priconne-redive.jp/fankit02/[0-9]*/"
    resURLListTemp = re.findall(pattern=pattern, string=s)

    如果没有获取任何内容,则说明此页面已经没有任何イベント内容,结束循环并确定爬虫范围。

  2. 对上个步骤获得的所有イベントURL进行遍历
    1) 按URL确定本地下载文件夹名。例如,第8856号イベント页面的本地下载文件夹名为8856
    如果不存在,则创建;如果已存在,则跳过创建。

    downloadImgs(resURL)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    resURL = resURL.rstrip("/")        # Delete '/' from right side.
    lastSlashPos = resURL.rfind('/')
    folderName = resURL[lastSlashPos + 1:]
    folderPath = "./allImg/" + folderName
    isExists = os.path.exists(folderPath)

    if isExists == False:
    os.makedirs(folderPath)
    print("\t├Create: Path \"" + folderPath + "\" not exists.")
    else:
    print("\t├Skip: Path \"" + folderPath + "\" exists.")

    2) 对URL进行GET请求,获得此页面内的所有有价值的JPG或PNG图片

    getImgURLs(resURL)
    1
    2
    3
    4
    5
    r = requests.get(resURL)
    s = r.text

    pattern = "https://priconne-redive.jp/ele-wp/wp-content/uploads/[0-9]+/[0-9]+/[a-zA-Z0-9]*\.(?:jpg|png)"
    imgURLList = re.findall(pattern=pattern, string=s)

    3) 对每一个图片的URL进行下载。
    如果不存在,则下载;如果存在,则跳过。

    downloadImgs(resURL)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    for index, imgURL in enumerate(imgURLList):
    # Create image
    lastSlashPos = imgURL.rfind('/')
    imgName = imgURL[lastSlashPos + 1:]
    imgPath = folderPath + '/' + imgName
    isExists = os.path.exists(imgPath)
    if isExists == False:
    with open(imgPath, 'wb') as imgFile:
    # Get image
    r = requests.get(imgURL)
    img = r.content

    imgFile.write(img)
    ...

完整代码

参考文献

Hexo

NexT 使用文档

Hexo发布博客引用自带图片的方法 - 简书

MarkDown页面添加锚点,跳转到本页指定位置

hexo代码块进阶写法 | Qcmoke’s Blog

正则表达式 - (?!), (?:), (?=)_u014644574的博客-CSDN博客_正则表的是(?=

fletchto99/hexo-sliding-spoiler