专栏名称: 图雀社区
一只图雀 @ 公众号「图雀社区」
51好读  ›  专栏  ›  图雀社区

爬虫养成记--顺藤摸瓜回首掏(女生定制篇)

图雀社区  · 掘金  ·  · 2020-03-16 03:21

正文

阅读 47

爬虫养成记--顺藤摸瓜回首掏(女生定制篇)

本文由 图雀社区 成员 灿若星空 写作而成,欢迎加入图雀社区,一起创作精彩的免费技术教程,予力编程行业发展。

如果您觉得我们写得还不错,记得 点赞 + 关注 + 评论 三连🥰🥰🥰,鼓励我们写出更好的教程💪

前情回顾

在上篇教程 爬虫养成记——先跨进这个精彩的世界(女生定制篇) 中我们已经可以将所有小哥哥的封面照片抓取下来,但仅仅是封面图片在质量和数量上怎么能满足小仙女们的要求呢?在本篇教程中,我们串起一根姻缘“线”,来把这一系列的小哥哥们都收入囊中。

出门先化妆

小仙女们出门约会总会“淡妆浓抹总相宜”,那爬虫出门去爬取数据,也得打扮打扮啊,不然怎么能让男神们都乖乖地跟着走呢?

爬虫的“化妆”可不是“妆前乳 --> 粉底 --> 遮瑕 --> 散粉 --> 画眉 --> 口红”等这些步骤,其目的是为了让对方网站更加确信来访者不是爬虫程序,而是一个活生生的人。人们通过操控浏览器来访问网站,那么爬虫程序只需要模仿浏览器就可以了。 那就来看看浏览器在打开网页时都画了那些“妆”。

8GMVwd.png

打开Chrome并打开调试台,切换到NetWork选项卡,此时访问 www.nanrentu.cc/sgtp/ , 这是时候会看到调试台里出现了很多链接信息,这么多链接到底哪个是我们所需要的呢?回想一下上一篇内容,首先是要获得HTML文档,再从此文档中提取出图片的链接,所以目标有了,就是找到浏览器获取到这个HTML文档的那个链接。

Chrome知道这么多链接信息肯定会让开发者陷入茫然,所以给链接进行了归类,点击上方Doc分类,再点击那唯一的一条链接,就会看到获取此HTML文档链接的详细信息了。此时我们关注主要Request Headers 这个里面的内容。浏览器通过http协议与服务器交互获取信息,爬虫是通过模仿浏览器发出http协议获取信息,其中最重要的一个模仿点就是Request Headers。

http协议里面的“瓶瓶罐罐”

让男生看女孩子化妆用的那些瓶瓶罐罐估计会陷入沉思,这是BB霜,那是粉底液,还有散粉、眼影、遮瑕膏,更不用说各种色号的口红啦。那女孩子看到这http里面的各项内容时估计也会一脸懵逼,其这比化妆品简单多了,我们只需简单了解,就能给爬虫画出精致妆容。

:authority: www.nanrentu.cc
:method: GET   // 自定义请求头 请求方法
:path: /sgtp/  // 自定义请求头 请求路径
:scheme: https // 自定义请求头 请求方式
// 所接受的内容格式
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
// 所接受的编码方式
accept-encoding: gzip, deflate, br
// 所接受的语言
accept-language: zh-CN,zh;q=0.9
// 缓存控制:告诉服务器客户端希望得到一个最新的资源
cache-control: max-age=0
cookie: UM_distinctid=170a5a00fa25bf-075185606c88b7-396d7407-100200-170a5a00fa3507; Hm_lvt_45e50d2aec057f43a3112beaf7f00179=1583326696,1583756661; CNZZDATA1274895726=1196969733-1583323670-%7C1583752625; Hm_lpvt_45e50d2aec057f43a3112beaf7f00179=1583756721
sec-fetch-dest: document
sec-fetch-mode: navigate
sec-fetch-site: none
sec-fetch-user: ?1
// 屏蔽HTTPS页面出现HTTP请求警报
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36
复制代码

这么多的信息不用都给爬虫加上,因为这网站的防爬措施等级不高,暂时只要关键的两个就可以了。

  • cookie: 这是存储在浏览器里面一段文本,有时包含了验证信息和一些特殊的请求信息
  • user-agent:用于标识此请求是由什么工具所发出的 关于User-Agent的详细信息可以参考此篇博文 谈谈 UserAgent 字符串的规律和伪造方法

但是当爬取其他网站时可能会有所需要,在这里赘述这么多原因就是希望大家能明白 伪装爬虫 的重要性,以及怎么获取这些伪装信息。

// 建立一个名叫headers的字典
headers = {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36',
    'cookie': 'UM_distinctid=170a5a00fa25bf-075185606c88b7-396d7407-100200-170a5a00fa3507; CNZZDATA1274895726=1196969733-1583323670-%7C1583925652; Hm_lvt_45e50d2aec057f43a3112beaf7f00179=1583326696,1583756661,1583926583; Hm_lpvt_45e50d2aec057f43a3112beaf7f00179=1583926583'
}
// 发送请求时带上请求头
response = requests.get(baseUrl,headers=headers)
复制代码

顺藤摸瓜

一个网站是由若干个网页组合而成的,网页中充满着各种超链接,从这网页链接到那个网页,如果我们想要更多小哥哥,那就得首先分析出串联起他们那些超链接,然后就可以顺藤摸瓜咯。

超连接元素.png

当把鼠标发放到标题上时,标题的颜色发生了变化,证明这一元素为超连接,点击标题浏览器会自动打开一个tab标签页,来显示网页,注意到下方的页码标签,是这些元素串联起了整个图集。

8EBD9U.png

点击“末页”观察url发生了什么变化

末页的url: www.nanrentu.cc/sgtp/36805_…

首页的url: www.nanrentu.cc/sgtp/36805.…

看起来有点意思了,末页的url比首页的url多了“_7”,接下来再点击分别进入第2页,第3页……观察url的变化,可得出下表。

页面 url
首页 www.nanrentu.cc/sgtp/36805.…
第2页 www.nanrentu.cc/sgtp/36805_…
第3页 www.nanrentu.cc/sgtp/36805_…
第4页 www.nanrentu.cc/sgtp/36805_…
第5页 www.nanrentu.cc/sgtp/36805_…
第6页 www.nanrentu.cc/sgtp/36805_…
第7页 www.nanrentu.cc/sgtp/36805_…

多点几个组图,也会发现同样规律。这样就明了很多了,我们已经分析清楚了这个跟“藤”的开头与结尾,接下来就可以敲出代码让爬虫开始“摸瓜”咯。

摸瓜第1步:提取标题链接

这个操作与上篇博文中所介绍的一样,打开调试台切换到Elements选项卡就能开始探索提取了。

8Ech4I.png

摸瓜第2步:提取末页链接,得出组图页数

8ERtu8.png

通过观察HTML元素结构,可发现包含末页的 <li> 标签为其父元素<ul>的倒数第二个子元素,所以可得出以下的css选择器

.page > ul > li:nth-last-child(2) > a

摸瓜第3步:根据首尾链接构造url

为了构造url更加方便,我们可以把首页 www.nanrentu.cc/sgtp/36805.… 变为 www.nanrentu.cc/sgtp/36805_… , 在浏览器中打开带有后缀的这个网址,依然能够成功访问到首页,不要问我为什么?这可能就是程序员之间的一种默契吧~

摸瓜第4步:存储图片,摸瓜成功

完整的代码如下:

import requests
from pyquery import PyQuery as pq
import uuid

headers = {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36',
    'cookie': 'UM_distinctid=170a5a00fa25bf-075185606c88b7-396d7407-100200-170a5a00fa3507; CNZZDATA1274895726=1196969733-1583323670-%7C1583925652; Hm_lvt_45e50d2aec057f43a3112beaf7f00179=1583326696,1583756661,1583926583; Hm_lpvt_45e50d2aec057f43a3112beaf7f00179=1583926583'
}
def saveImage(imgUrl,name):
    imgResponse = requests.get(imgUrl)
    fileName = "学习文件/%s.jpg" % name
    if imgResponse.status_code == 200:
        with open(fileName, 'wb') as f:
            f.write(imgResponse.content)
            f.close()

def getPic(urlArray):
    for url in urlArray:
        res = requests.get(url,headers=headers)
        if res.status_code == 200:
            doc = pq(res.text)
            imgSrc = doc('.info-pic-list > a > img').attr('src')
            print(imgSrc)
            saveImage(imgSrc,uuid.uuid1().hex)
    

def createUrl(indexUrl,allPage):
    baseUrl = indexUrl.split('.html')[0]
    urlArray = []
    for i in range(1,allPage):
        tempUrl = baseUrl+"_"+str(i)+".html"
        urlArray.append(tempUrl)
    return urlArray

def






请到「今天看啥」查看全文