教你爬取妹子图之拿下“女神”(二)

611 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情


教你爬取妹子图之拿下“女神”(二)

声明

本人所有逆向、破解及爬虫相关教程均是以纯技术的角度来探讨研究和学习,严禁使用教程中提到的技术去破解、滥用、伤害其他公司及个人的利益,以及将以下内容用于商业或者非法用途。

前情回顾

上回书说到,我们已经把分析的明明白白,就差正式行动了,我们这节开始,正式展开我们的行动!!!

Item编写

这里的item可以理解为数据库里面的ORM,我们把要爬取的字段定义成模型,页面上可以直接提取的就直接进行提取,不能的就更新进去,然后直接把item插入到数据库中就可以

帖子模型

直接贴代码:

class PostItem(Item):
    # 标题
    title = Field(css_select='h1::text')
    # 描述
    desc = Field(css_select='.longConWhite div[style]::text')
    # 图片
    images = Field(css_select='img[id^="imglist_"]::attr(src)', many=True)
    # 标签
    tags = Field(css_select='.post-tags a::text', many=True)
    # 着装
    dress = Field()
    # 风格
    style = Field()
    # 体征
    signs = Field()
    # 场景
    scene = Field()
    # 地域
    regional = Field()
    # 机构
    organization = Field()
    # 套图ID
    post_id = Field()
    # 爬取来源
    web_src = Field()
    # 插入时间
    created_at = Field()

作者模型

class AuthorItem(Item):
    # 简介
    desc = Field(css_select='.star2-intro-bd p::text')
    # 中文名
    chinese_name = Field()
    # 英文名
    english_name = Field()
    # 名字
    name = Field()
    # 生日
    birthday = Field()
    # 职业
    job = Field()
    # 三围
    size_3 = Field()
    # 出生地点
    addr = Field()
    # 身高
    height = Field()
    # 体重
    weight = Field()
    # 星座
    constellation = Field()
    # 生肖
    chinese_zodiac = Field()
    # 地域
    regional = Field()
    # 身材
    figure = Field()
    # 体征
    signs = Field()
    # 组合
    group = Field()

爬虫类

这里就正式开始编写爬虫相关的代码,一步一步来,先写全量爬取的,然后再这基础上进行逐步完善

开始URL

看这里,这是爬取图集的地方。因为我们是全量爬取,所以这里就直接粗暴的写死,爬取1067页,而不是动态的获取最大页数,因为反正后期页要做增加更新的。

所以开始url部分可以这么写:

class XiuSeSpider(Spider):
    start_urls = [f'https://www.xsnvshen.co/album/?p={i}' for i in range(1, 1068)]

解析图集

就是爬取帖子的基本信息了,信息的提取我们上一节都已经说过了,这里就是直接用就好:

class XiuSeSpider(Spider):
    # 先用一页进行测试
    start_urls = [f'https://www.xsnvshen.co/album/?p={i}' for i in range(1, 2)]

    async def parse(self, response: Response):
		pass

我们来运行看看:

会发现,直接失败了,我们有理由怀疑是不是有些参数没有传递进去,所以我们把url复制到请求工具上面看看:

会发现响应码是404,并且页面返回了一个数据验证码的界面,大家第一时间想到的一定是怎么打码,怎么验证之类的,但是请大家不要着急,先分析一波,首先我们并没有那么快速率切长时间的请求,而是只请求了一个地址而已,那么一定是触发了某种逻辑才会弹出验证码,这时可以在考虑是不是请求头传递的问题,但在仔细想想这个可能性是不大的,因为返回是页面就是html的,所以这个应该往cookies上面去思考,所以我们这时可以把浏览器的cookies复制进去试试,会发现成功了:

然后我们把cookies精简一下,测试测试到底是哪个或哪几个cookies的效果,经过测试发现是一个名为:gcha_sf=1665503816;的cookie的效果,但是这个值很明显是一个时间戳,很有可能是时间到了之后就不能用了,我们把这个值修改一下再看看,会发现没有校验值是多少,只是判断了有没有名为gcha_sf的cookies,这时我们把这个cookies传递进去再看看:

class XiuSeSpider(Spider):
    start_urls = [f'https://www.xsnvshen.co/album/?p={i}' for i in range(1, 2)]

    async def parse(self, response: Response):
		pass


def main():
    setting = Setting(cookies={"gcha_sf": "1"})
    XiuSeSpider.start(setting=setting)

会发现已经成功了,但我们如果细心的话,会发现url被改变了,也就是被重定向过,从*.com重定向到了*.co,而且网站logo上面页明确的写的是xsnvshen.com,也就是这个域名是做推广及宣传的,那么就可以简单推断,这个域名的反爬机制可能会很弱,我们试一下:

发现只是把顶级域名修改了一下,请求头、cookies都没有就成功了,我们再代码里面也这么写试一下:

class XiuSeSpider(Spider):
    start_urls = [f'https://www.xsnvshen.com/album/?p={i}' for i in range(1, 2)]
    
    ......

会发现同样成功了,我们继续编写提取的代码:

class XiuSeSpider(Spider):
    start_urls = [f'https://www.xsnvshen.com/album/?p={i}' for i in range(1, 2)]

    async def parse(self, response: Response):
        urls = response.css('.itemimg::attr(href)').getall()
        for url in response.to_url(urls):
            yield self.get(url=url, callback=self.parse_post)

    async def parse_post(self, response: Response):
        post_item = await PostItem.extract(response=response)
        post_item.web_src = response.url
        post_item.post_id = int(response.url.split('/')[-1])


def main():
    setting = Setting()
    XiuSeSpider.start(setting=setting)

'.itemimg::attr(href)'是提取页面中每一个图集的选择器,然后再调用解析帖子的方法parse_post,这样我们的帖子的基本信息就爬取到了

总结

先暂时来个总结,这一节我们初步的编写了爬虫的数据模型和爬虫的代码,然后我们使用两种方法处理了反爬虫。想和大家说的是遇到问题不要慌,冷静心细,然后可以站在对方角度上思考一下,我们下节继续