持续创作,加速成长!这是我参与「掘金日新计划 · 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,这样我们的帖子的基本信息就爬取到了
总结
先暂时来个总结,这一节我们初步的编写了爬虫的数据模型和爬虫的代码,然后我们使用两种方法处理了反爬虫。想和大家说的是遇到问题不要慌,冷静心细,然后可以站在对方角度上思考一下,我们下节继续