问题定义
今天我们来搞一搞公主连结官方发布的壁纸和头像的爬虫及下载。
公主连结HP:
プリンセスコネクト!Re:Dive (プリコネR) 公式サイト | Cygames
主要涉及的网站:
ファンキット | プリンセスコネクト!Re:Dive (プリコネR) 公式サイト | Cygames
其中的イベント部分为官方发布的所有的活动,包含我们想要的壁纸和头像,因此对此进行爬虫可达到我们目的。
イベント页面
我们想要下载的壁纸和头像(例:第8856号イベント页面)
状况分析
对于每一个ファンキット页面,我们发现合法的页面的标号是从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
虽然正常返回页面,但页面里不存在任何一个イベント页面。如下图:
这成为我们的爬虫终止条件。
在每一个ファンキット页面里存在多个イベント页面。对于每一个イベント页面,其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) 与基本URL(https://priconne-redive.jp/fankit02/page
)拼接递增的页码号,生成各个ファンキット页面URL,并设置type=event
进行GET请求,获取HTML内容:getResURLs(base_url) 1
2
3
4url = base_url + "/" + str(i)
params = {'type': 'event'} # https://.../page/1 -> 2/?type=event
r = requests.get(url, params=params)
s = r.text2) 对返回的HTML内容进行如下正则匹配:
getResURLs(base_url) 1
2pattern = "https://priconne-redive.jp/fankit02/[0-9]*/"
resURLListTemp = re.findall(pattern=pattern, string=s)如果没有获取任何内容,则说明此页面已经没有任何イベント内容,结束循环并确定爬虫范围。
对上个步骤获得的所有イベントURL进行遍历
1) 按URL确定本地下载文件夹名。例如,第8856号イベント页面的本地下载文件夹名为8856
。
如果不存在,则创建;如果已存在,则跳过创建。downloadImgs(resURL) 1
2
3
4
5
6
7
8
9
10
11resURL = 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
5r = 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
14for 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)
...
完整代码
1 | import re |