爬虫养成记先跨进这个精彩的世界(女生定制篇) - V2EX
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 5998 次点击
    这是一个创建于 1995 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我们研发开源了一款基于 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 respons.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 推荐当成 offic 来用。。。爬虫还是算了吧。。。
    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
    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     Solana     1029 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 23:07 PVG 07:07 LAX 16:07 JFK 19:07
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86