使用Python编写多线程爬虫抓取百度贴吧邮箱与手机号_零零散散是什么号码最好(1)

本文提供了一套完整的Python学习路径,包括学习路线、所需工具、电子书、视频教程、实战案例、面试准备和多线程编程技术,强调了知识体系和系统学习的重要性,鼓励读者加入学习社区共同进步。
摘要由CSDN通过智能技术生成

如果你也是看准了Python,想自学Python,在这里为大家准备了丰厚的免费学习大礼包,带大家一起学习,给大家剖析Python兼职、就业行情前景的这些事儿。

一、Python所有方向的学习路线

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

二、学习软件

工欲善其必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

三、全套PDF电子书

书籍的好处就在于权威和体系健全,刚开始学习的时候你可以只看视频或者听某个人讲课,但等你学完之后,你觉得你掌握了,这时候建议还是得去看一下书籍,看权威技术书籍也是每个程序员必经之路。

四、入门学习视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

五、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

成为一个Python程序员专家或许需要花费数年时间,但是打下坚实的基础只要几周就可以,如果你按照我提供的学习路线以及资料有意识地去实践,你就有很大可能成功!
最后祝你好运!!!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

HTTP协议:

我们的爬虫抓取数据本质上就是不停的发起http请求,获取http响应,将其存入我们的电脑中。了解http协议有助于我们在抓取数据的时候对一些能够加速抓取速度的参数能够精准的控制,比如说keep-alive等。

threading模块(多线程):

我们平时编写的程序都是单线程程序,我们写的代码都在主线程里面运行,这个主线程又运行在python进程中。关于线程和进程的解释可以参考阮一峰的博客:进程与线程的一个简单解释 - 阮一峰的网络日志

在python中实现多线程是通过一个名字叫做threading的模块来实现。之前还有thread模块,但是threading对于线程的控制更强,因此我们后来都改用threading来实现多线程编程了。

关于threading多线程的一些用法,我觉得这篇文章不错:[python] 专题八.多线程编程之thread和threading 大家可以参考参考。

简单来说,使用threading模块编写多线程程序,就是先自己定义一个类,然后这个类要继承threading.Thread,并且把每个线程要做的工作代码写到一个类的run方法中,当然如果线程本身在创建的时候如果要做一些初始化工作,那么就要在他的__init__方法中编写好初始化工作所要执行的代码,这个方法就像php,java中的构造方法一样。

这里还要额外讲的一点就是线程安全这个概念。通常情况下我们单线程情况下每个时刻只有一个线程在对资源(文件,变量)操作,所以不可能会出现冲突。但是当多线程的情况下,可能会出现同一个时刻两个线程在操作同一个资源,导致资源损坏,所以我们需要一种机制来解决这种冲突带来的破坏,通常有加锁等操作,比如说mysql数据库的innodb表引擎有行级锁等,文件操作有读取锁等等,这些都是他们的程序底层帮我们完成了。所以我们通常只要知道那些操作,或者那些程序对于线程安全问题做了处理,然后就可以在多线程编程中去使用它们了。而这种考虑到线程安全问题的程序一般就叫做“线程安全版本”,比如说php就有TS版本,这个TS就是Thread Safety线程安全的意思。下面我们要讲到的Queue模块就是一种线程安全的队列数据结构,所以我们可以放心的在多线程编程中使用它。

最后我们就要来讲讲至关重要的线程阻塞这个概念了。当我们详细学习完threading模块之后,大概就知道如何创建和启动线程了。但是如果我们把线程创建好了,然后调用了start方法,那么我们会发现好像整个程序立马就结束了,这是怎么回事呢?其实这是因为我们在主线程中只有负责启动子线程的代码,也就意味着主线程只有启动子线程的功能,至于子线程执行的那些代码,他们本质上只是写在类里面的一个方法,并没在主线程里面真正去执行他,所以主线程启动完子线程之后他的本职工作就已经全部完成了,已经光荣退场了。既然主线程都退场了,那么python进程就跟着结束了,那么其他线程也就没有内存空间继续执行了。所以我们应该是要让主线程大哥等到所有的子线程小弟全部执行完毕再光荣退场,那么在线程对象中有什么方法能够把主线程卡住呢?thread.sleep嘛?这确实是个办法,但是究竟应该让主线程sleep多久呢?我们并不能准确知道执行完一个任务要多久时间,肯定不能用这个办法。所以我们这个时候应该上网查询一下有什么办法能够让子线程“卡住”主线程呢?“卡住”这个词好像太粗鄙了,其实说专业一点,应该叫做“阻塞”,所以我们可以查询“python 子线程阻塞主线程”,如果我们会正确使用搜索引擎的话,应该会查到一个方法叫做join(),没错,这个join()方法就是子线程用于阻塞主线程的方法,当子线程还未执行完毕的时候,主线程运行到含有join()方法的这一行就会卡在那里,直到所有线程都执行完毕才会执行join()方法后面的代码。

Queue模块(队列):

假设有一个这样的场景,我们需要抓取一个人的博客,我们知道这个人的博客有两个页面,一个list.php页面显示的是此博客的所有文章链接,还有一个view.php页面显示的是一篇文章的具体内容。

如果我们要把这个人的博客里面所有文章内容抓取下来,编写单线程爬虫的思路是:先用正则表达式把这个list.php页面的所有链接a标签的href属性抓取下来,存入一个名字叫做article_list的数组(在python中不叫数组,叫做list,中文名列表),然后再用一个for循环遍历这个article_list数组,用各种抓取网页内容的函数把内容抓取下来然后存入数据库。

如果我们要编写一个多线程爬虫来完成这个任务的话,就假设我们的程序用10个线程把,那么我们就要想办法把之前抓取的article_list平均分成10份,分别把每一份分配给其中一个子线程。

但是问题来了,如果我们的article_list数组长度不是10的倍数,也就是文章数量并不是10的整数倍,那么最后一个线程就会比别的线程少分配到一些任务,那么它将会更快的结束。

如果仅仅是抓取这种只有几千字的博客文章这看似没什么问题,但是如果我们一个任务(不一定是抓取网页的任务,有可能是数学计算,或者图形渲染等等耗时任务)的运行时间很长,那么这将造成极大地资源和时间浪费。我们多线程的目的就是尽可能的利用一切计算资源并且计算时间,所以我们要想办法让任务能够更加科学合理的分配。

并且我还要考虑一种情况,就是文章数量很大的情况下,我们要既能快速抓取到文章内容,又能尽快的看到我们已经抓取到的内容,这种需求在很多CMS采集站上经常会体现出来。

比如说我们现在要抓取的目标博客,有几千万篇文章,通常这种情况下博客都会做分页处理,那么我们如果按照上面的传统思路先抓取完list.php的所有页面起码就要几个小时甚至几天,老板如果希望你能够尽快显示出抓取内容,并且尽快将已经抓取到的内容展现到我们的CMS采集站上,那么我们就要实现一边抓取list.php并且把已经抓取到的数据丢入一个article_list数组,一边用另一个线程从article_list数组中提取已经抓取到的文章URL地址,然后这个线程再去对应的URL地址中用正则表达式取到博客文章内容。如何实现这个功能呢?

我们就需要同时开启两类线程,一类线程专门负责抓取list.php中的url然后丢入article_list数组,另外一类线程专门负责从article_list中提取出url然后从对应的view.php页面中抓取出对应的博客内容。

但是我们是否还记得前面提到过线程安全这个概念?前一类线程一边往article_list数组中写入数据,另外那一类的线程从article_list中读取数据并且删除已经读取完毕的数据。但是python中list并不是线程安全版本的数据结构,因此这样操作会导致不可预料的错误。所以我们可以尝试使用一个更加方便且线程安全的数据结构,这就是我们的子标题中所提到的Queue队列数据结构。

同样Queue也有一个join()方法,这个join()方法其实和上一个小节所讲到的threading中join()方法差不多,只不过在Queue中,join()的阻塞条件是当队列不为空空的时候才阻塞,否则继续执行join()后面的代码。在这个爬虫中我便使用了这种方法来阻塞主线程而不是直接通过线程的join方式来阻塞主线程,这样的好处是可以不用写一个死循环来判断当前任务队列中是否还有未执行完的任务,让程序运行更加高效,也让代码更加优雅。

还有一个细节就是在python2.7中队列模块的名字是Queue,而在python3.x中已经改名为queue,就是首字母大小写的区别,大家如果是复制网上的代码,要记得这个小区别。

getopt模块:

如果大家学过c语言的话,对这个模块应该会很熟悉,他就是一个负责从命令行中的命令里面提取出附带参数的模块。比如说我们通常在命令行中操作mysql数据库,就是输入mysql -h127.0.0.1 -uroot -p,其中mysql后面的“-h127.0.0.1 -uroot -p”就是可以获取的参数部分。

我们平时在编写爬虫的时候,有一些参数是需要用户自己手动输入的,比如说mysql的主机IP,用户名密码等等。为了让我们的程序更加友好通用,有一些配置项是不需要硬编码在代码里面,而是在执行他的时候我们动态传入,结合getopt模块我们就可以实现这个功能。

hashlib(哈希):

哈希本质上就是一类数学算法的集合,这种数学算法有个特性就是你给定一个参数,他能够输出另外一个结果,虽然这个结果很短,但是他可以近似认为是独一无二的。比如说我们平时听过的md5,sha-1等等,他们都属于哈希算法。他们可以把一些文件,文字经过一系列的数学运算之后变成短短不到一百位的一段数字英文混合的字符串。

python中的hashlib模块就为我们封装好了这些数学运算函数,我们只需要简单的调用它就可以完成哈希运算。

为什么在我这个爬虫中用到了这个包呢?因为在一些接口请求中,服务器需要带上一些校验码,保证接口请求的数据没有被篡改或者丢失,这些校验码一般都是hash算法,所以我们需要用到这个模块来完成这种运算。

json:

很多时候我们抓取到的数据不是html,而是一些json数据,json本质上只是一段含有键值对的字符串,如果我们需要提取出其中特定的字符串,那么我们需要json这个模块来将这个json字符串转换为dict类型方便我们操作。

re(正则表达式):

有的时候我们抓取到了一些网页内容,但是我们需要将网页中的一些特定格式的内容提取出来,比如说电子邮箱的格式一般都是前面几位英文数字字母加一个@符号加http://xxx.xxx的域名,而要像计算机语言描述这种格式,我们可以使用一种叫做正则表达式的表达式来表达出这种格式,并且让计算机自动从一大段字符串中将符合这种特定格式的文字匹配出来。

sys:

这个模块主要用于处理一些系统方面的事情,在这个爬虫中我用他来解决输出编码问题。

time:

稍微学过一点英语的人都能够猜出来这个模块用于处理时间,在这个爬虫中我用它来获取当前时间戳,然后通过在主线程末尾用当前时间戳减去程序开始运行时的时间戳,得到程序的运行时间。

如图所示,开50个线程抓取100页(每页30个帖子,相当于抓取了3000个帖子)贴吧帖子内容并且从中提取出手机邮箱这个步骤共耗时330秒。

urllib和urllib2:

这两个模块都是用于处理一些http请求,以及url格式化方面的事情。我的爬虫http请求部分的核心代码就是使用这个模块完成的。

MySQLdb:

这是一个第三方模块,用于在python中操作mysql数据库。

这里我们要注意一个细节问题:mysqldb模块并不是线程安全版本,意味着我们不能在多线程中共享同一个mysql连接句柄。所以大家可以在我的代码中看到,我在每个线程的构造函数中都传入了一个新的mysql连接句柄。因此每个子线程只会用自己独立的mysql连接句柄。

cmd_color_printers:

这也是一个第三方模块,网上能够找到相关代码,这个模块主要用于向命令行中输出彩色字符串。比如说我们通常爬虫出现错误,要输出红色的字体会比较显眼,就要使用到这个模块。

自动化爬虫的错误处理:

如果大家在网络质量不是很好的环境下使用该爬虫,会发现有的时候会报如图所示的异常,这是我为了偷懒并没有写各种异常处理的逻辑。

现在能在网上找到很多很多的学习资源,有免费的也有收费的,当我拿到1套比较全的学习资源之前,我并没着急去看第1节,我而是去审视这套资源是否值得学习,有时候也会去问一些学长的意见,如果可以之后,我会对这套学习资源做1个学习计划,我的学习计划主要包括规划图和学习进度表。

分享给大家这份我薅到的免费视频资料,质量还不错,大家可以跟着学习

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 7
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值