在Python爬虫工程师学会记住大数据的时代,网络爬虫已经成为获取数据的重要手段。但是想要学好爬虫并不是那么简单。首先知识点和方向太多,涉及到计算机网络、编程基础、前端开发、后端开发、App开发与逆向工程、网络安全、数据库、运维、机器学习、数据分析等,它像一张大网络一样把一些主流技术栈连接在一起。因为涵盖的方向比较多,所以要学的东西也很零散、杂乱。很多新手不知道该学什么知识,在学习过程中也不知道如何解决反爬的问题。让我们在这篇文章中做一些归纳和总结。一些最基础的新手网站往往没有任何反爬措施。比如在某个博??客站点,如果我们要爬取整个站点,我们可以沿着列表页面爬取到文章页面,然后向下爬取文章的时间、作者、正文等信息。代码怎么写?使用Python的requests等库就够了,写一个基本的逻辑,一路获取每篇文章的源码,然后使用XPath,BeautifulSoup,PyQuery或者正则表达式,或者粗略的字符串匹配,获取你想要的源码把内容剪下来,加个文字保存,就大功告成了。代码很简单,就是几个方法调用。逻辑很简单,几个循环加存储。最后,我们可以看到每篇文章都保存在我们的电脑里了。当然有的同学可能不太会写代码或者懒得写,所以使用基本的可视化爬取工具,比如某爪鱼、某传人采集器,也可以通过可视化点击的方式爬下数据。如果存储稍有扩展,可以连接MySQL、MongoDB、Elasticsearch、Kafka等保存数据,实现持久化存储。以后查询或操作会更方便。反正效率再高,一个完全没有反爬的网站,用最基本的方式也能搞定。至此,你说你了解爬虫?不,它甚至不接近。对于想要更轻松的学习Python开发技术,Python爬虫,Python大数据分析,人工智能等技术的初学者,这里我给大家分享一套系统的教学资源,加上我搭建的Python技术的学习裙子;七八四七五八二一四,一起学习。有相关开发工具,学习教程,专业老司机每天在线直播分享知识技术答疑解惑!Ajax、动态渲染随着互联网的发展,前端技术也在不断变化,数据加载方式不再是简单的服务端渲染。现在大家可以看到很多网站的数据可能是以接口的形式传输的,或者即使不是接口也是一些JSON数据,然后通过JavaScript来渲染。这个时候再想用requests爬取也没用,因为requests爬取的源代码是服务端渲染的,浏览器看到的页面结果和requests得到的结果是不一样的。真正的数据是由JavaScript执行的。数据源可能是Ajax,页面中的一些数据,或者是一些ifame页面等,但大多数情况下可能是通过Ajax接口获取的。因此,很多时候,需要对Ajax进行分析,知道这些接口的调用方法后,再用程序进行模拟。但是有些接口带有加密参数,比如token、sign等,不好模拟,那怎么办呢?一种方法是分析网站的JavaScript逻辑,把里面的代码挖出来,弄清楚这些参数是怎么构造的,弄清思路后再用爬虫模拟或者重写。如果自己解决了,那么直接模拟的方法效率会高很多,需要一定的javascript基础。当然,有些网站的加密逻辑太强大了。你可能一周都解决不了,最后放弃。向上。那么解决不了或者不想解决怎么办呢?这时候可以通过模拟浏览器直接爬取简单粗暴的方法,比如Puppeteer、Pyppeteer、Selenium、Splash等,这样爬出来的源代码就是真正的网页代码,数据自然轻松提取,同时还绕过了解析Ajax和一些JavaScript逻辑的过程。这样一看到就可以爬取,难度也不是很大。同时模拟浏览器,很少有法律问题。但实际上后一种方式也会遇到各种反爬的情况。现在很多网站都会识别webdriver,看你用的是selenium等工具,直接kill或者不返回数据,所以你遇到这种网站我得专门解决这个问题。用单线程爬虫模拟多进程、多线程、协程的情况比较简单,但是有个问题就是速度慢。爬虫是IO密集型任务,因此大多数情况下它们可能在等待网络响应。如果网络响应速度慢,他们必须一直等待。但是这段空闲时间其实可以让CPU做更多的事情。那我们该怎么办呢?打开更多线程。所以这个时候我们可以在一些场景下加入多进程、多线程。多线程虽然有GIL锁,但是对爬虫的影响并没有那么大,所以使用多进程和多线程可以成倍提高爬虫速度,对应的库有threading和multiprocessing。异步协程更棒。有了aiohttp、gevent、tornado等,基本上你想做多少并发就做多少,但是要慢慢来,不要挂了别人的网站。总之有了这几个,爬虫速度就会提高。但是提高速度并不一定是好事。接下来肯定是反爬了,封你IP,封你账号,弹出验证码,返回假数据,所以有时候爬慢好像是个办法?分布式多线程、多进程、协程都可以加速,但毕竟还是单机爬虫。要真正实现规模化,你必须依赖分布式爬虫。分销的核心是什么?资源共享。比如爬虫队列共享、去重指纹共享等。我们可以使用一些基本的队列或者组件来实现分布式,比如RabbitMQ、Celery、Kafka、Redis等,但是经过很多人的尝试,自己实现了一个分布式爬虫,在性能和可扩展性上总会出现一些问题。当然,特别厉害的人除外。很多公司其实都有自己开发的一套分布式爬虫,跟业务的联系比较紧密。这当然是最好的。现在主流的Python分布式爬虫还是基于Scrapy,对接Scrapy-Redis、Scrapy-Redis-BloomFilter或者使用Scrapy-Cluster等,都是基于Redis共享爬行队列,总会有一些内存问题。所以也有人考虑连接其他的消息队列,比如RabbitMQ、Kafka等,来解决一些问题,效率也不错。总之,要提高爬取效率,必须掌握分布。验证码爬虫难免会遇到反爬,验证码就是其中之一。想要能够反爬,首先要能够解码验证码。现在大家可以看到很多网站都有各种各样的验证码,比如最简单的图形验证码。如果验证码的文字是规则的,可以通过OCR或者基础模型库进行识别。如果不想做可以直接连接打码平台做,准确率还是有的。但是,您现在可能看不到任何图形验证码。都是行为验证码,比如某某验证,某某屏蔽等,国外也有很多,比如reCaptcha等。对于一些比较简单的,比如滑动的,可以想办法找出差距,比如图像处理对比,深度学习识别。至于轨迹,写一个模拟正常人的行为,加点抖动之类的。有了轨迹后如何模拟?如果你牛逼,可以直接分析验证码的JavaScript逻辑,输入轨迹数据,然后就可以得到里面的一些加密参数,直接把这些参数放到表单或者界面中。你可以直接使用它。当然你也可以通过模拟浏览器进行拖拽,也可以通过一定的方式获取加密参数,也可以直接通过模拟浏览器一起登录,可以用cookies进行爬取。当然,拖拽只是验证码的一种,还有文本选择、逻辑推理等,实在不想做的话,可以找个打码平台解决,模拟一下,但毕竟,要花钱,有的专家会选择自己训练深度学习相关的模型,收集数据,标注,训练,针对不同的业务训练不同的模型。这样有了核心技术,就不用再花钱找编码平台,再研究验证码的逻辑仿真,加密参数就可以解决了。不过有的验证码很稀有,有的我没管理过。当然,有些验证码可能会因为请求太频繁而弹出,可以通过更改IP什么的解决。BlockingIPBlockingIP也是一个让人头疼的问题。有效的方法是更换代理。代理有很多种,市面上有免费的,收费的也太多了。首先,你可以使用市面上的免费代理,自己搭建一个代理池,收集全网所有的免费代理,然后添加测试人员不断测试。测试的网址可以改成你要抓取的网址。这样,通过测试的一般都可以直接用来爬取你的目标网站。付费代理也是如此。很多商户都提供代理提取接口,一次请求就可以提取几十个、上百个代理。我们还可以将它们连接到代理池。但是,该机构也有各种套餐。公开代理、独家代理等的质量和被封杀的概率也不同。有些商家还使用隧道技术设置代理,让我们不知道代理的地址和端口,代理池由他们维护,比如云云,使用起来更省心,但可控性很困难。更差。还有更稳定的代理,比如拨号代理、蜂窝代理等,接入成本会高一些,但也能在一定程度上解决一些IP阻塞的问题。不过这些东西都不简单,为什么一个好的高隐特工无缘无故爬不上去,后面的一些事情就不说了。在账号被封之前需要模拟一些信息才能登录。如果你爬的太快,其他网站会直接封禁你的账号,没什么好说的。比如你爬公众号,如果有人封了你的WX账号,就完了。一种解决办法当然是放慢频率,控制节奏。另一种方法是查看其他终端,如手机页面、App页面、wap页面等,看是否有绕过登录的方法。另一个更好的方法是转移。如果你有足够的账户,建立一个池子,比如Cookies池,Token池,Sign池,反正不管什么池,多个账户的Cookies和Token都放在这个池子里,使用的时候从里面随机取一个.如果要保证抓取效率不变,那么相对于20个账号和100个账号,每个账号对应的Cookies和Token的使用频率会变成原来的1/5,被封的概率也会变大1/5。然后降低了。奇怪的反爬上面说了几种主流的反爬,当然还有很多奇怪的反爬。比如返回假数据,返回图片数据,返回乱序数据,返回诅咒数据,返回求饶数据,都看具体情况。这些反爬你得小心了。之前看到直接返回rm-rf/的反爬并不少见。如果你正好有一个模拟执行并返回结果的脚本,那后果你自己想象吧。JavaScript逆向工程脱颖而出。随着前端技术的进步和网站反爬虫意识的增强,很多网站选择在前端下功夫,即在前端对一些逻辑或代码进行加密或混淆。当然,这不仅仅是为了保护前端代码不被轻易窃取,更重要的是防止爬取。比如很多Ajax接口都会携带一些参数,比如sign,token等,这些在上一篇文章中已经提到。我们可以用上面提到的Selenium等方法来爬取这种数据,但是总的来说效率太低了。毕竟它模拟的是网页渲染的全过程,真正的数据可能只是隐藏在一个小小的界面中。如果我们真的能够找出一些接口参数的逻辑,用代码来模拟执行,效率会成倍提高,而且也能在一定程度上避免上面提到的反爬现象。但问题是什么?难的。webpack一方面是将前端代码压缩转码成一些bundle文件,一些变量的意义已经丢失,不容易恢复。然后有些网站加了一些混淆器机制,把前端代码变成你根本看不懂的东西,比如字符串拆解和改组、变量十六进制化、控制流扁平化、无限调试、控制台禁用等等等等,前面-结束代码和逻辑已经面目全非。有的是用WebAssembly等技术直接编译前端核心逻辑,只能慢慢捡。虽然有些有一定的技巧,但总的来说还是需要不少时间。但是一旦解决了,一切都会好起来的。怎么说?就像一道奥数题,解决了就升天了,解决不了就GG。很多公司招聘爬虫工程师都会问有没有JavaScript逆向基础,破解过哪些网站,比如某宝某号某文章等,如果查到需要的可能会直接聘用你。每个网站的逻辑不一样,难度也不一样。当然,应用程序爬虫不仅仅是网络爬虫。随着互联网时代的发展,现在越来越多的企业选择把数据放在APP上,有的公司甚至只有APP没有网站。所以只能通过App爬取数据。怎么爬?最基本的是抓包工具。Charles和Fiddler捕获界面后可以用它来模拟界面。如果接口有加密参数怎么办?一种方式,可以边爬边处理,比如mitmproxy直接监听接口数据。另一方面,你可以使用Hook,比如你也可以在Xposed上获取。那么爬坡时如何实现自动化呢?你不能用手戳它。其实工具很多,安卓原生的adb工具也有。Appium现在是比较主流的解决方案。当然还有其他的精灵可以实现。最后,有时我真的不想经历自动化过程。就是想挖出里面的一些接口逻辑,只好逆向工程了。IDAPro、jdax、FRIDA等工具派上用场。当然,这个过程和逆向JavaScript一样痛苦,你甚至可能不得不阅读汇编指令。一次掉一根头发也不是不可能。上面的情报部分你已经很熟悉了。恭喜,你已经超越了80%、90%的爬虫玩家。当然,专门做JavaScript逆向和App逆向的都是食物链顶端的男人。据说已经不属于爬虫类了,这种神我们也不算在里面,反正我也不算。除了上面的一些技巧,在某些情况下,我们可能还需要结合一些机器学习的技巧,让我们的爬虫变得更聪明。比如现在很多博客和新闻文章,页面结构相似度比较高,要提取的信息也比较相似。比如如何区分一个页面是索引页还是详情页?如何提取详情页的文章链接?如何解析文章页面的页面内容?这些其实可以通过一些算法计算出来。因此,一些智能解析技术也开始运行,比如提取详情页,朋友写的GeneralNewsExtractor表现非常好。假设我有一个需求,我要爬取10000个新闻网站的数据,是否需要一个一个写XPath?给我写下来。如果有智能分析技术,在容忍一定误差的情况下,分分钟就能搞定。总之,如果我们也能学会这部分,我们的爬虫技术会如虎添翼。运维也是一件大事。爬虫和运维也是息息相关的。比如写完一个爬虫,如何快速部署到100台主机上运行。比如如何灵活的监控各个爬虫的运行状态。比如爬虫有代码变动,如何快速更新。比如如何监控一些爬虫的内存占用和CPU消耗。比如如何科学地控制爬虫的定时运行,比如爬虫出现问题如何及时收到通知,如何建立科学的报警机制等。在这里,每个人都有自己的部署方式,比如使用Ansible,当然。如果你使用Scrapy,你就有了Scrapyd,然后你可以通过一些管理工具来完成一些监控和定时任务。但是我现在用的比较多的是Docker+Kubernetes,再加上一套DevOps,比如GitHubActions、AzurePipelines、Jenkins等,快速实现分发部署。你们有的用crontab做定时任务,有的用apscheduler,有的用管理工具,有的用Kubernetes。我用Kubernetes比较多,定时任务也很容易实现。至于监控,有很多,一些专门的爬虫管理工具自带一些监控告警功能。一些云服务也有一些监控功能。我正在使用Kubernetes+Prometheus+Grafana。CPU、内存、运行状态一目了然。告警机制在Grafana中配置也很方便。它支持Webhook、电子邮件,甚至是钉子。对于数据存储和监控,使用Kafka和Elasticsearch也很方便。我主要用后者,然后配合Grafana,对爬取的数据量,爬取速度等监控一目了然。结语至此,爬虫涵盖的部分知识点大同小异。怎么样,梳理一下,是不是涵盖了计算机网络、编程基础、前端开发、后端开发、App开发与逆向、网络安全、数据库、运维、机器学习?以上总结可以看作是爬虫新手到爬虫高手的路径。其实每个方向都有很多可以研究的点。如果每一个点都被提炼出来,那将是非常了不起的。爬虫经常学习学习,成为全栈工程师或全职工程师,因为你可能真的无所不知。可是没办法,都是被爬虫逼的,若不是被生活所困,谁还想有才华?
