V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
huan1043269994
V2EX  ›  Python

爬虫养成记——先跨进这个精彩的世界(女生定制篇)

  •  
  •   huan1043269994 · 2020-04-26 09:24:10 +08:00 · 5515 次点击
    这是一个创建于 1705 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我们研发开源了一款基于 Git 进行技术实战教程写作的工具,我们图雀社区的所有教程都是用这款工具写作而成,欢迎 Star

    如果你想快速了解如何使用,欢迎阅读我们的 教程文档哦

    发刊词

    这是一套基于实战的系列教程,从最简单的爬虫程序开始,授人予渔,详细剖析程序设计的思路,完整展现爬虫是如何一步步调试到最终完成。分享关于爬虫的各种知识、技巧,旨在帮助大家认识爬虫、设计爬虫、使用爬虫最后享受爬虫带给我们在工作和生活上的各种便利。

    预备知识

    1. 基本的 python 编程知识
      1. 这里使用 Python3 作为开发环境
      2. 同时具备基本的装包知识
    2. 基本的网页编程知识
    3. 初步了解 HTTP 协议

    这是最简单的计算机程序

    说起爬虫每个人都或多或少的听过与之相关的内容,觉得它或高深、或有趣。作为一名写代码四五年的初级码农来看,爬虫程序是计算机程序里面最简单也是最有趣的程序。只要会上网冲浪就有写爬虫程序的天赋

    爬虫为什么是虫呢?因为虫子的头脑比较简单,爬虫程序也是 ++“一根筋”++ ,不需要讳莫如深的数学知识,也不用设计精巧的各类算法。我们只需要用计算机能听懂的“大白话”平铺直叙就可以啦。

    开发爬虫的基本套路

    一句话总结所有爬虫程序的作用: 模拟人类上网的操作,以此来查找、下载、存储数据。 接下来我要以 男人图这个网站为例,分享套路。

    step 1: 打开目标网址

    此处强烈推荐 Chrome

    首先打开这个网址: https://www.nanrentu.cc/sgtp/, 会看到以下界面

    3I7ph6.png

    现在我们只是用浏览器手动打开了这个页面,接下来我们要用代码,让程序也打开这个页面。这就要分析一下浏览器是如何打开这个页面的了,请看简易流程图。

    3IHqeJ.png

    在 python 中,可以使用 requests 这一工具包来发送 HTTP 请求。为了了解程序所“看到” 页面是什么样子的,我们需要把程序所得到 HTML 文件保存到本地,然后再用浏览器打开,就能和程序感同身受了。从而达到“人机合一”的境界。

    光说不练假把式,让我们马上来新建一个 index.py 文件,然后在其中编写如下内容:

    import requests
    url = "https://www.nanrentu.cc/sgtp/"
    response = requests.get(url)
    if response.status_code == 200:
        with open("result.html",'a',encoding="utf-8") as f:
            f.write(response.text)
    

    在浏览器打开写入的 HTML 文件是这样的

    3IqM36.png

    3IqK9x.png

    这怎么和在浏览器中看到的不一样呢?

    这个时候我就要亮出一件绝世宝贝————Chrome 调试台(按 F12 )来给您分析一波了。 3ILhFA.png

    其实我们在浏览器中看到的页面并不仅仅是 HTML 页面,而是 css 、js 、html 以及各种媒体资源综合在一起并有浏览器最终渲染而出页面,红框的部分,标出了在这个过程中所加载的各个资源。

    当我们用程序去请求服务器时,得到仅仅是 HTML 页面,所以程序和我们所看到的页面就大相径庭了。不过没关系 HTML 是主干,抓住了主干其他的只需要顺藤摸瓜就可以了。

    step2:找到目标资源

    打开这个网址以后,各位小仙女就可以各取所需咯,想体验萧亚轩的快乐嘛?那目标就是小鲜肉;馋彭于晏的那样的身子了?那肌肉帅哥就是你的菜。此外韩国欧巴,欧美型男也是应有尽有。

    人类是高级生物,眼睛会自动聚焦的目标身上,但是爬虫是“一根筋”啊,它可不会自动聚焦,我们还得帮它指引道路。

    写过前端页面的朋友都知道 CSS 样式用过各种选择器来绑定到对应的节点上,那么我们也可以通过 CSS 的选择器来选中我们想要的元素,从而提取信息。Chrome 中已经准备了 CSS 选择器神器,可以生成我们想要元素的选择器。

    具体过程如下:第三步为好好欣赏小哥哥们~

    3o8dJg.png

    step3:解析页面

    这个时候要介绍页面解析神器pyquery,这个工具库可以通过我们所复制的 CSS 选择器,在 HTML 页面中查找对应元素,并且能很便捷地提取各种属性。那么接下来我们就把这个小哥哥解析出来吧。

    我们首先安装 PyQuery 这个包,具体可以使用 pip 包管理器安装,然后将代码修改成如下这样:

    import requests
    from pyquery import PyQuery as pq
    url = "https://www.nanrentu.cc/sgtp/"
    response = requests.get(url)
    if response.status_code == 200:
        with open("result.html",'w',encoding="utf-8") as f:
            f.write(response.text)
        # 开始解析
        doc = pq(response.text)
        # 把复制的选择器粘贴进去
        # 选择对应的节点
        imgElement = doc('body > div:nth-child(5) > div > div > div:nth-child(2) > ul > li:nth-child(3) > a > img')
        # 提取属性,获取图片链接
        imgSrc = imgElement.attr('src')
        # 将图片链接输出在屏幕上
        print(imgSrc)
    
    

    step4:存储目标

    这么好看的小哥哥怎么能只让他在互联网上呆着呢?把他放进硬盘里的学习资料文件夹里才是最安全的。接下来,我们就把小哥哥放到碗里来。

    下载图片的过程其实和抓取 HTML 页面的流程是一样的,也是利用 requests 发送请求从而获取到数据流再保存到本地。

    import requests
    from pyquery import PyQuery as pq
    url = "https://www.nanrentu.cc/sgtp/"
    response = requests.get(url)
    if response.status_code == 200:
        with open("result.html",'w',encoding="utf-8") as f:
            f.write(response.text)
        doc = pq(response.text)
        imgElement = doc('body > div:nth-child(5) > div > div > div:nth-child(2) > ul > li:nth-child(3) > a > img')
        imgSrc = imgElement.attr('src')
        print(imgSrc)
        # 下载图片
        imgResponse = requests.get(imgSrc)
        if imgResponse.status_code == 200:
            # 填写文件路径 以二进制的形式写入文件
            with open('学习文件 /boy.jpg', 'wb') as f:
                f.write(imgResponse.content)
                f.close()
    
    

    此时先来看看效果

    3odp8K.png

    四步虫

    至此仅仅十多行代码就完成了一个小爬虫,是不是很简单。其实爬虫的基本思路就这四步,所谓复杂的爬虫就是在这个四步的基础上不断演化而来的。爬虫最终的目的是为了获取各种资源(文本或图片),所有的操作都是以资源为核心的。

    1. 打开资源
    2. 定位资源
    3. 解析资源
    4. 下载资源

    更多的小哥哥

    通过上述步骤我们只能获取到一个小哥哥,集美们就说了,我直接右击鼠标下载也可以啊,干嘛费劲写爬虫呢?那接下来,我们就升级一波选择器,把小哥哥们装进数组,统统搞到碗里来。

    重构代码

    为了以后写代码更方便,要先进行一个简单的重构,让代码调理清晰。

    1. 增加入口函数
    2. 封装对于图片的操作

    重构后的代码如下:

    import requests
    from pyquery import PyQuery as pq
    
    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 main():
        baseUrl = "https://www.nanrentu.cc/sgtp/"
        response = requests.get(baseUrl)
        if response.status_code == 200:
            with open("result.html",'w',encoding="utf-8") as f:
                f.write(response.text)
            doc = pq(response.text)
            imgElement = doc('body > div:nth-child(5) > div > div > div:nth-child(2) > ul > li:nth-child(3) > a > img')
            imgSrc = imgElement.attr('src')
            print(imgSrc)
            saveImage(imgSrc,'boy')
            
    if __name__ == "__main__":
        main()
    

    升级选择器

    有过前端编程经验的同学们可以看出来,Chrome 自动生成的选择器指定了具体的某个子元素,所以就只选中了一个小哥哥,那么接下来我们要分析出通用的选择器,把臭弟弟们一锅端。

    3oy7nK.png

    多拿着鼠标点点这个调试台,一层层地看这个 HTML 文件的元素层级,找到其中相同重复的地方,这就是我们的突破口所在。

    我们可以看出图片都在一个类名为 h-piclist 的 <ul> 标签中,那么我们可写出以下的选择器 .h-piclist > li > a > img。这样就选中了这一页所有的图片元素。接着用一个 for 循环遍历就可以了。

    import requests
    from pyquery import PyQuery as pq
    
    # 引入 UUID 为图片命名
    import uuid
    
    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 main():
        baseUrl = "https://www.nanrentu.cc/sgtp/"
        response = requests.get(baseUrl)
        if response.status_code == 200:
            with open("result.html",'w',encoding="utf-8") as f:
                f.write(response.text)
            doc = pq(response.text)
            # 选则这一页中所有的目标图片元素
            imgElements = doc('.h-piclist > li > a > img').items()
            # 遍历这些图片元素
            for i in imgElements:
                imgSrc = i.attr('src')
                print(imgSrc)
                saveImage(imgSrc,uuid.uuid1().hex)
    
    if __name__ == "__main__":
        main()
    

    无法下载的图片

    3o2Ygs.png

    可以看出图片的连接已经全部拿到了,但是当去下载图片时却发生了一些意外,请求图片竟然没有反应。这是哪里出了问题呢?图片连接全部拿到,证明代码没毛病,把图片链接放到浏览器里正常打开,证明连接没毛病,那现在可能就是网络有毛病了。

    1. 网速慢
    2. 网络波动
    3. 对方网站有防爬措施
    4. ……

    这时候因素很多,我们首先用最简单的方法来解决问题,断线重连。把笔记本 WIFI 重启,重新加入网络,再运行程序。

    惊喜来了,臭弟弟们成功入库。

    3o2T8H.png

    当然啦,这种方式并不是银弹,我们需要有更多的技巧来提升爬虫程序的“演技”,我们的爬虫程序表现的越像个人,那我们获取资源的成功率就会越高。

    看到这里,应该跨进爬虫世界的大门了,如果这个世界有主题曲的话那么一定是薛之谦的《演员》接下来的教程中会一遍磨砺“演技”,一遍获取更多的小哥哥。

    想要学习更多精彩的实战技术教程?来图雀社区逛逛吧。

    也欢迎关注我们的公众号:图雀社区,鼓励我们写出更好的教程!

    23 条回复    2020-05-09 16:27:37 +08:00
    815979670
        1
    815979670  
       2020-04-26 09:34:23 +08:00   ❤️ 7
    每天一个入狱小技巧(滑稽)
    chwhsen
        2
    chwhsen  
       2020-04-26 09:46:41 +08:00 via Android
    怎么一提到爬虫就是爬图呢,给人的第一印象就很怪
    rookielq
        3
    rookielq  
       2020-04-26 09:55:36 +08:00
    这个教程写的就很 nice
    fhsan
        4
    fhsan  
       2020-04-26 09:58:25 +08:00
    搞得我找工作看到爬虫就害怕入狱
    Mithril
        5
    Mithril  
       2020-04-26 09:59:13 +08:00
    Python 和爬虫已经被各种教程和培训班玩烂了。。。
    o0
        6
    o0  
       2020-04-26 10:17:59 +08:00
    先跨进这个精彩的世界,再跨进当地的看守所。
    JB18CM
        7
    JB18CM  
       2020-04-26 10:20:30 +08:00
    学爬虫之前应该先学习中国法律, 和参考爬虫被抓案例 , 尽量避免入狱
    Cmdhelp
        8
    Cmdhelp  
       2020-04-26 10:30:47 +08:00
    加上线程池分布式队列
    stevenkang
        9
    stevenkang  
       2020-04-26 10:54:02 +08:00
    狱友养成记——先获得一份犯罪证明再进入编程行业
    enaxm
        10
    enaxm  
       2020-04-26 10:58:30 +08:00
    python 推荐当成 office 来用。。。爬虫还是算了吧。。。
    siebenundvierzig
        11
    siebenundvierzig  
       2020-04-26 12:33:37 +08:00
    太麻烦了,像我女朋友直接找了我就完事了
    Huelse
        12
    Huelse  
       2020-04-26 12:35:45 +08:00
    狱友信物
    adekyou06
        13
    adekyou06  
       2020-04-26 13:41:33 +08:00
    太好了!又可以多加几个女狱友了!
    renmu
        14
    renmu  
       2020-04-26 14:01:57 +08:00 via Android
    直接让男朋友学就好了(笑
    stop9125
        15
    stop9125  
       2020-04-26 14:26:36 +08:00
    好了,学会了,女朋友在哪领
    zuosiruan
        16
    zuosiruan  
       2020-04-26 17:11:42 +08:00
    图挂了?
    izzy27
        17
    izzy27  
       2020-04-26 17:44:08 +08:00
    只要是用心写的教程我都支持 已经 star 了
    labulaka521
        18
    labulaka521  
       2020-04-26 18:43:09 +08:00 via Android
    从定制到入狱
    jasamboro
        19
    jasamboro  
       2020-04-26 18:59:07 +08:00
    大佬,图挂了,为啥不选个主流一些的图床呢
    crella
        20
    crella  
       2020-04-26 19:11:15 +08:00 via Android
    https://www.v2ex.com/t/603129

    https://v2ex.com/t/665304#;

    这两篇文章主要讲 chrome debugging port,带上 selenium 。

    讲真的,任何一门排行榜前 10 的语言都有简易爬虫的方法,但是也就只有 python 的简易爬虫教程天天搬出来了。

    Ruby 技术链:HTTParty 或 OpenURI 、Nokogiri 、JSON 或 YAML 、SQLite 或 MySQL2 (等数据库)、ERB(用于将爬虫数据转化为 html)
    learningman
        21
    learningman  
       2020-04-26 21:11:10 +08:00
    @crella 因为 python 上手比较快,骗小白方便
    Meltdown
        22
    Meltdown  
       2020-04-26 21:54:46 +08:00 via Android
    有没有女神定制篇
    getu
        23
    getu  
       2020-05-09 16:27:37 +08:00
    imgElement = doc('body > div:nth-child(5) > div > div > div:nth-child(2) > ul > li:nth-child(3) > a > img')

    这个 css 选择器是怎么出来的?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5585 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 08:14 · PVG 16:14 · LAX 00:14 · JFK 03:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.