花瓣一日游

作者: 慕长风啊 | 来源:发表于2019-02-02 14:25 被阅读8次

朋友工作上有需求,要在花瓣上采集1w+的图片,于是我就帮忙写了个爬虫。


初拿到账号,登上去看了眼网站布局。是这个样子:

花瓣用户主页

布局简洁明了,爬取思路也很清晰:

先拿到一个board(画板)链接

board

进入一个board后拿到所有pin(图片)的链接就ok了

pins

按照以前写爬虫的套路,抓包,分析网络请求,模拟网络请求,数据提取等一套操作下来,这种小爬虫,十来分钟,保准交差!

然而...flag立得有些早了(/捂脸)

刚开始提取数据的时候就遇到了点小阻碍

F12下看到的页面中想提取的数据长这个样子:

html

但是响应的数据包里的数据格式却是这个样子:

response

看来页面是经过JavaScript动态渲染过了,这下惯用的bs4库是派不上用场了。
看到网上有人用Selenium库来模拟浏览器操作,我觉得没有必要,太影响性能了。

不如首先确定下要爬取的board链接在响应数据中的位置吧,Ctrl+F在页面源代码里搜一下。
有点小坑,直接搜索“/boards/45651489/”还搜不到,还得截取board_id才能搜到:

board_link

不过既然在源码里找到了要爬取的数据就好说了,直接上正则提取吧:

r = requests.get("http://login.meiwu.co/{}/".format(USER_NAME),
                 cookies=self.cookies, headers=self.headers)
result = re.search(
    r'app.page\[\"user\"\] = (.*?)};', r.text).group(1) + "}"
boards = json.loads(result)['boards']
for board in boards:
    self.boards.put((board['board_id'], board['title'])) # 用队列存储board_id和board_title

本以为数据提取这部分就算大功告成了,后面就可以松一口气了,没想到...

loading

花瓣还用上了Ajax异步加载...

简单科普一下,有时候我们用requests库模拟请求的时候,返回数据和浏览器中看到的不一样,一种情况就是上面那样经过JS渲染了,还有一种情况是返回的数据好像不完整,比如这里页面下拉能看到更多的board,但是我们一次request是看不到后来的这些数据的,这种数据加载是一种异步加载方式,原始页面不包含后续的数据,当你下拉的时候,页面会向后台请求某个接口获取数据,然后才会被处理呈现到浏览器上,这其实就是发送了一个Ajax请求。

幸好不是第一次遇到了,以前爬小密圈的时候还觉得蛮棘手,现在也算有些经验了,就是又要费把子力气。

先打开F12,筛选XHR类型的请求,然后加载下一页board,提取XHR请求的特征

XHR

分析后发现,主要参数为max,其他几个参数可以不用管
其值是上一页中最后一个board_id
类比我之前爬过的小密圈,其中一个关键值是上一页最后一条帖子的发言时间
找到这个规律后,接下来的工作就容易很多了:
提取每一页board的最后一个board_id,然后构造下一页的request

r = requests.get("http://login.meiwu.co/{}/?jrkb9krs&limit=10&wfl=1&max={}".format(
    USER_NAME, board['board_id']), cookies=self.cookies, headers=self.headers)

经过以上的工作,用户页面的所有画板链接就都提取到手了,接着就是对board页面里的所有图片进行链接提取了,套路和上面是一模一样的,这里就不赘述了。

总的说来,如果有前端基础,再加上些Python功底,写爬虫是件很easy的事情。
我自己其实不懂前端,全凭着些Python编程的经验,所以上面写的可能有些错漏之处,有大牛看到的话还望多指点。

最后补充两点

  1. 数据存储和查重
    为了方便后面对图片进行多线程断点下载,保存数据的时候需要注意下,其实每个pin(图片)都有个key,这个key可以定位到图片的下载地址,同样也可以用于图片查重操作。
    这里我将代码分成了两部分去写:
    第一部分遍历每个board,并获取其中每张图片的key, raw_text(图片描述)和对应的board_title(用于图片分类),然后将所有图片信息保存成json文件。
    第二部分就是读取json文件,获取每张图片的下载链接,完成一个简单的多线程图片下载任务就行了,单张图片下载前会借助os模块读取文件目录,依据key或者图片名判断图片是否已经存在。

  2. 反反爬虫
    其实最令我头疼的是这个问题,写代码前的准备工程中我就发现,花瓣的访问很不稳定,尤其用爬虫模拟访问时,经常出现连接错误,而且摸不清规律。
    为此代码中对大部分request都用上了while语句加上随机数休眠,由于不清楚其反爬虫机制,暂时只是加上了headers和休眠措施,目前测试情况来看已经满足需求了,后面有空尝试搭建代理池再试试效果。

附完整代码:
https://github.com/Moofeng/Spider/tree/master/huaban

相关文章

  • 花瓣一日游

    朋友工作上有需求,要在花瓣上采集1w+的图片,于是我就帮忙写了个爬虫。 初拿到账号,登上去看了眼网站布局。是这个样...

  • 去鼋头渚赏樱

    无锡太湖鼋头渚一日游。 鼋头渚内樱花开得正艳,已经有不少花瓣落了。景区中的樱花有三万多株,品种多达一百多种...

  • 花瓣落在花瓣之上

    感觉到秋天的温润,从这朵小菊花开始。淡淡的黄色,明亮的花蕊,窄长的花瓣上几滴露珠,我见犹怜。 那天清晨,花瓣掉落在...

  • 花瓣

    我从不忍心看那凋零的花销蚀于泥土 总是把落在地面的花瓣拾起 装在我心爱的花篮里 爬上高高的顶峰扬了它 风带走了那些...

  • 花瓣

    风总算带走了自私的梅 只留下冬的血 淌进黄土的襁褓里 羊水破了 燕尾剪断了春的脐带 疼痛开出了四瓣 一瓣给了远方的...

  • 花瓣

    那开在梦里 你的 贴着我的 分不清是谁的芳香 ……

  • 花瓣

    我的心是一片小小的、干枯的 玫瑰花瓣 你轻轻划了火柴 一瞬间 花瓣成灰 都来不及疼

  • 花瓣

    你像一枚 风干了的书签 在书中 躲藏了千年 我穿越风霜雪雨 只为能与你相见 心与心的链接 无须语言 爱情 就是这么...

  • 花瓣

    作品名称:花瓣。联想到一首老歌:在那桃花盛开的地方。

  • 花瓣

    作品叫花瓣。中间是花瓣,外面是各种颜色的水晶。

网友评论

    本文标题:花瓣一日游

    本文链接:https://www.haomeiwen.com/subject/zzejsqtx.html