继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

《python分布式爬虫打造搜索引擎》(上)----学习笔记

慕姐8265434
关注TA
已关注
手记 1275
粉丝 222
获赞 1065

第一章 windows(以及linux)下的环境搭建

1. python打造分布式爬虫:

开发工具IDE:pycharm
数据库: mysql,redis,elasticsearch
开发环境:virtualenv虚拟环境

2. 需要学会的是:

pycharm的安装和使用
mysql和navicat的安装和使用
virtualenv和virtualenvwrapper的安装和配置

3. 关于Linux下启动pycharm的两种方法:

百度进入pycharm的官网后选择download并且选择相应的linux版本,下载下来的文件是绿色的。

  • (1) 在linux下使用命令可以直接启动,找到bin文件夹中的pycharm.sh文件,运行。具体linux下的操作命令如图:

    webp

    linux下运行pycharm的命令

  • (2) 除了这种方法以外,还有另外一个快捷键通过命令就可以直接启动,首先在linux下面可以建立自己的命令,使用vim命令编辑用户总目录下面的bashrc文件,按shift+G到.bashrc文件的最后一行。

    webp


    :wq命令是退出这个文件,编辑完成之后,一定要运行source ~/.bashrc,命令让这个配置文件生效,生效之后直接运行pycharm命令就可以启动pycharm软件了。

4. pycharm的使用之项目虚拟环境的设置方法

webp

关于创建项目的虚拟环境

5. 检查windows上是否已安装mysql的方法

  1. 在cmd中输入mysql,如果提示找不到命令,除了没安装,还有可能是mysql的bin路径没有设置到变量path中

  2. 确定是安装好的,输入mysql还是报错,是因为没有指定用户名以及输入密码,使用命令mysql -uroot -p,接下来会提示输入命令。

一般关于mysql的操作很少使用cmd控制台的,可以使用navicat软件(轻量级,用于mysql的连接和管理)。

5.1 在navicat中关于mysql使用:

webp

  • 在navicat中连接好mysql就可以新建数据库了,注意字符集和排序方法的选择:


    webp

5.2 navicat中数据库内容的传输有两种方法:
  1. 直接传输

webp

webp

  1. 转化成sql文件

webp

6. 在linux下安装mysql

  1. 直接使用命令sudo ~到主目录中,再使用命令sudo apt-get install mysql-server,前面必须加sudo,因为这是系统软件,否则是没有权限的,刚安装的时候都需要设置用户名和密码的。

  2. 在linux下检查mysql是否正常启动,使用命令ps aux|grep mysqld,前面的ps aux是检查所有进程的,grep是过滤出mysql相关的进程。进入mysql后命令exit;退出。

webp

7. 如何配置虚拟机的mysql与外部系统navicat连接:

(1) 关于如何配置mysql,使得外部的navicat可以和虚拟机内linux的mysql相互连接。默认情况下是连接不进来的,需要修改配置,方法如下:

webp

:wq退出文件,接下来使用命令sudo service mysql restart重启mysql服务。再用上面的方法检查是否启动成功,如果有相应的进程号代表启动成功。

(2) 使用虚拟机的外部windows上的navicat连接时,需要知道虚拟机的ip,使用命令ifconfig可以查看到,在navicat设置连接时报错。

webp

(3) Linux下设置mysql的用户权限,其相关命令是:

webp

webp

8. Windows下安装Python2和python3以及虚拟环境的配置

如果同时安装了python2和python3,在cmd中输入python还是2的环境,这是因为环境变量的path里面,只配置了2.7的路径,如果想要变成3,那么就需要将python3的路径加入到path变量中,有两个版本会引起冲突,所以删除2的路径,就可以将python默认的版本为3了。

如果是在linux环境下,可以直接运行命令sudo apt-get install python3.5,可以直接指明python的版本,在下载最新的linux版本时候,python2和3都已经默认安装上的,只不过默认的版本是python2.7。如果需要使用python3,在linux环境下,只需要输入命令python3就切换成3的环境了。

8.1 Windows python虚拟环境的安装和配置:
  • 虚拟环境最大的好处就是可以将开发环境相互隔离,而不互相影响,比如说有的项目是使用2来开发的,有的使用3来开发的,用虚拟环境下就能很好的解决。

在安装开发包之前,说一个pip的技巧,某些开发包在下载过程中会很慢,经常出现timeout的情况,解决这个问题,可以配置一下下载第三方包的镜像,可以加速下载和安装。百度搜索python豆瓣源就可以搜索到镜像,并且还提示了第三方包的安装方法:


webp

  1. 在cmd中输入命令pip install virtualenv安装虚拟环境

  2. 学会使用豆瓣源,用-i指定镜像源,安装django,命令pip install -i https://pypi.douban.com/simple/ django

  3. 安装了虚拟环境之后,就可以新建虚拟环境了,命令virtualenv scrapytest,后面为虚拟环境的名称,这个虚拟环境会被安装到对应的cmd目录下,比如C:\Users\mtudou>,就可以找到scrapytest的一个文件夹,里面存放的python最初的包。

  4. 激活虚拟环境,进入scripts文件夹,使用命令activate.bat完成激活。使用deactivate.bat退出当前虚拟环境。

webp

如何指定新建的虚拟环境的python版本,使用命令virtualenv -p ...\python.exe scrapypython3,前面的...表示python对应版本的安装路径,即python.exe的路径。

8.2 Linux安装python虚拟环境:
1. 命令`sudo apt-get install python-virtualenv`安装2. 命令`virtualenv pythonha2`,新建一个虚拟空间3. 命令`cd pythonha2`进入虚拟环境目录4. 这里和windows不一样,**它的脚本在bin目录下**,windows是在scripts目录下,所以命令`cd bin/`5. 命令`source activate`启动虚拟环境
8.3  Windows下安装virtualenvwrapper

由于我们看到对于每一个虚拟环境,我们都必须记住它的路径,并且要找到相应的scripts目录或者bin目录,才来启动很麻烦,所以有一个专门的虚拟环境管理工具virtualwrapper。

  1. 命令pip install virtualenvwrapper,安装管理工具

  2. 命令workon,列出所有的虚拟环境

  3. 命令mkvirtualenv 名称,新建一个新的虚拟环境,默认是放在Users/administrator/envs里面的,实际上是可以修改这个目录的,在高级系统环境变量设置中,新建一个WORKON_HOME变量,就可以自己指定路径了。如果新建了新的envs地址,使用workon命令就找不到之前的虚拟环境了,可以把原先的虚拟环境全部拷贝过去。所有通过mkvirtualenv创建的虚拟环境都会到work_home这个目录下。

  4. 命令workon 名称,直接进入该虚拟环境,再也不需要考虑虚拟环境的路径了,命令“deactivate”直接退出该虚拟环境。

  5. 如果同时安装了python2和3,要指定虚拟环境使用那个版本,命令mkvirtualenv --python=python.exe路径 名称

  • 有时候安装包的时候报错,记住这个网址:https://www.lfd.uci.edu/~gohlke/pythonlibs/,很多时候安装失败都可以在这里找到对应的版本,主要是windows的版本,找到对应的python版本的msi文件,就可以直接下载下来。进入该文件所在的目录,使用pip intsall 文件名完成安装。如果是安装到某个虚拟环境,要先进入指定的虚拟环境

8.4 Linux下安装virtualenvwrapper
  1. pip install virtualenvwrapper

  2. 安装好了之后不能像windows下一样直接使用mkvirtualenv的,因为没有配置,使用命令sudo find / -name virtualwrapper.sh,找到这个文件

  3. 找到文件位置之后,就需要配置source文件,使用命令vim ~/.bashrc打开总管理文件,在最后一行,配置其中两条路径。

webp

webp

第二章 爬虫相关基础知识

2.1 scrapy简介

做爬虫的时候,经常都会听到scrapy VS requests + beautifulsoup的组合,在本次分布式爬虫实现中只用scrapy而不用后者的原因是:

  1. requests和beautifulsoup都是库,scrapy是一个框架,框架中可以应用requests等,可以集合很多第三方库

  2. scrapy基于twisted,性能是最大的优势,异步IO框架

  3. scrapy方便扩展,提供了很多内置的功能,提高开发速度

  4. scrapy内置的css和xpath selector(对html或者xml进行分析)非常方便,beautifulsoup缺点就是慢

实践中还是会用到requests,但是不会用到beautifulsoup,因为它的功能可以直接使用scrapy的select完成。

2.2 互联网上网页分类

静态网页,事先在服务器端生成好的页面,内容是不会变的
动态网页,从服务器端取数据返回
webservice(restapi),也是属于动态网页的一种,只是通过ajax方式和后台交互的一种技术

2.3 爬虫能做什么

  1. 搜索引擎-百度,google,垂直领域搜索引擎(有一个目标,知道自己到底爬什么数据)

  2. 推荐引擎-今日头条(根据浏览习惯猜测感兴趣的内容进行推送)

  3. 机器学习的数据样本

  4. 数据分析-金融数据分析,舆情分析

2.4 正则表达式

提问:为什么有css或者xpath selector还要学正则表达式,有时候根据selector获得了整个标签内的内容,但是还要进行进一步的筛选,比如里面的数字信息等

  1. 可以帮我们判断某个字符串是否符合某一个模式

  2. 提取整个字符串里面的重要的部分信息

webp

正则表达式里面的特殊字符

正则表达式中常用字符的用法介绍:
^ : 以什么字符开头
$ : 以什么字符结尾
. : 任意字符
* :出现任意次数,0次或者更多次
():还提取按模式取出来的子串。例如,".*(b.*b).*"表示不管前后是什么的两个b之间的子串
? :非贪婪匹配模式,默认的情况下,匹配是贪婪模式,匹配最大长度
    对于 "bobby123"这个待匹配的,结果就是bb,而不是bobb,所以这就是贪婪,反向匹配(或者理解成直到结束符合的最后一个结果)
    非贪婪匹配就是从左边开始,只需要出现一个结果就可以了,".*?(b.*?b).*"表示对两个b从左到右只要出现一次就可    ".*?(b.*b).*"第二个b不要问好,那么第二个b就是贪婪模式,会持续匹配到最后一个b
+ :字符至少出现一次
{1}:前面的字符出现一次
{3,}: 要求前面的字符必须出现3次以上
{2,5}:前面的字符至少出现2次,最少出现5次| : 或的关系
[] : 中括号里面的内容只要满足任何一个即可,也可以是一个区间,中括号里面的^表示不等于,中括号里面的符号就是符号,不是特殊符号的含义
\s :表示空格符
\S : 刚好与小s的意思相反,只要不是空格都可以
\w : 表示[A-Za-z0-9_]其中的任意一个字符
\W : 与\w的意思刚好相反
[\u4E00-\u9FA5] : unicode编码,含义是汉字,意思是只要出现汉字就可以。
\d : 表示数字

代码实例:

import re"""
line = "study in 南京大学" # 待匹配的字符串
# # if line == "boooooooobaaby123":  # 一般匹配方法
regex_str = ".*?([\u4E00-\u9FA5]+大学)" # 定义模式,用到了^.*三种特殊字符
match_obj = re.match(regex_str,line)  # 接收匹配的结果
if match_obj:  # 参数第一个是模式字符串,第二个是待匹配的字符串
    print(match_obj.group(1))  # 匹配子串结果

""""""
? :非贪婪匹配模式,匹配最大长度,默认的情况下,匹配是贪婪模式
():还提取按模式取出来的子串。例如,".*(b.*b).*"表示不管前后是什么的两个b之间的子串,使用group()方法可以得到第一种子串的结果
    如果还有子串,则group(2)表示第二个子串结果,最外层括号为第一个
    对于 "bobby123"这个待匹配的,结果就是bb,而不是bobb,所以这就是贪婪,反向匹配
    非贪婪匹配就是从左边开始,只需要出现一个结果就可以了,".*?(b.*?b).*"表示对两个b从左到右只要出现一次就可
    ".*?(b.*b).*"第二个b不要?,那么第二个b就是贪婪模式,会持续匹配到最后一个b
"""# 关于一个匹配多种格式输入能找出生日的模式str = "XXX出生于2001年6月1日"str = "XXX出生于2001/6/1"str = "XXX出生于2001-6-1"str = "XXX出生于2001-06-01"str = "XXX出生于2001-06"regex_str = ".*出生于(\d{4}[年/-]\d{1,2}([月/-]\d{1,2}|[月/-]$|$))"match_obj = re.match(regex_str,str)if match_obj:
    print(match_obj.group(1))

2.5 深度优先和广度优先算法

这一节主要了解网站的树结构,深度优先算法和实现,广度优先算法和实现

爬虫的基本原理,一个网站的url设计是分层的,树形结构,能够让我们爬取网站的时候更加有策略。在设计网站url时候是不会有环路的,但是在真实网站url链接的结构中,是有环路的。比如,从首页到达某个页面,这个页面上会有返回首页的链接。如果一直进入这个死循环,那么其他页面就爬取不到内容了。所以需要用到网页的去重。伯乐在线网站的文章爬取其中获取到的文章url是不会重复的,就不需要去重。但大多数文章都需要去重。

webp


webp

scrapy默认使用深度优先实现的,深度优先使用递归实现的广度优先是采用队列来实现的

webp


webp

2.6 爬虫去重策略

  1. 将访问过的url保存到数据库中,获取url时查询一下是否爬过了。虽然数据库中有缓存,但是每次都查询效率很低。

  2. 将url保存到set中。只需要O(1)的代价就可以查询到url,但是内存占用会越来越大
    假设有1亿条url,那么就需要1亿 x 2byte x 50字符/1024/1024/1024=8G

  3. url经过md5等方法哈希后保存到set中,将url压缩到固定长度而且不重复,scrapy实际上就是应用这种方法

  4. 用bitmap方法,将访问过的url通过hash函数映射到某一位,对内存压缩更大,缺点是冲突比较高

  5. bloomfilter方法对bitmap进行改进,多重hash函数降低冲突可能性。即减少内存,又减少冲突。

2.7 弄清楚unicode编码和utf8编码

字符串编码,写文件以及网络传输过程中,调用某些函数,经常碰到提示编码错误。

看一下ASCII和unicode编码:

  • 字母A用ASCII编码十进制是65,二进制 0100 0001

  • 汉字"中" 已近超出ASCII编码的范围,用unicode编码是20013二进制是01001110 00101101

  • A用unicode编码只需要前面补0二进制是 00000000 0100 0001

乱码问题解决了,但是如果内容全是英文,unicode编码比ASCII编码需要多一倍的存储空间,传输也会变慢。所以此时出现了可变长的编码utf-8,把英文:1字节,汉字3字节,特别生僻的变成4-6字节,如果传输大量的英文,utf8作用就很明显。Unicode编码虽然占用空间但是因为占用空间大小等额,在内存中处理会简单一些。

关于windows下编码格式问题:


webp


webp

关于linux下的编码问题:


webp

第三章 网站内容爬取之创建项目

首先爬取一个网站前,我们需要分析网络的url结构,伯乐在线的网站结构是采用顶级域名下有二级域名,来区分每种类别的信息,并且在文章专栏里面,有一个http://web.jobbole.com/all-posts/是所有文章的总链接,在这个链接下,分页显示了所有的文章内容。

因此对于这种爬取内容有一个总链接的话,就不需要采用深度优先或者广度优先策略,只需要将这个总链接下的每一页的内容取出即可。说到每一页,查看url特点,发现就是在链接后面修改了页数,但是不能用这个方法,因为网站上文章数发生变化时,就必须要去修改源码。
如果是对每个分页上的写一页的链接进行跟踪,那么有多少页都无所谓了。

3.1 通过命令行创建pycharm scrapy项目步骤:

  1. 创建一个虚拟环境article_spider:mkvirtualenv article_spider

  2. 在这个虚拟环境内安装scrapy: pip install -i https://pypi.douban.com/simple/ scrapy
    注意安装的时候可能会报错,twisted找不到,那么就去https://www.lfd.uci.edu/~gohlke/pythonlibs/下载安装包,手动安装,安装的时候必须也是在这个虚拟环境内

  3. 建立scrapy项目,pycharm里面没有scrapy的工程,所以需要在命令行内手动安装
    进入pycharm工作目录cd d:\PycharmProjects
    进入虚拟环境workon article_spider
    创建scrapy项目专门爬取伯乐在线的文章scrapy startproject ArticleSpider,如下图,即为创建成功

    webp

  4. 在pycharm中打开刚创建的项目

3.2 pycharm项目工程文件的理解

scrapy.cfg: 类似于django的配置,它大量的借鉴了django的设计理念
settings.py: 包含了很多scrapy的配置,工程名字,spider_modules也指明了存放spiders的路径
pipelines.py: 做跟数据存储相关的
middlewares.py: 可以存放自己定义的middlewares,让scrapy变得更加可控
items.py: 有点类似于django里面的form,定义数据保存的格式
spiders文件夹:里面存放具体某个网站的爬虫,scrapy会去这个文件夹里面找有多少个爬虫文件,只需要在这里面继承了spiders,就会被scrapy找到

3.3 创建具体的spider方法

刚创建好项目的时候这个文件夹是空的,默认并没有创建网站爬取的模板,但是提供了命令,scrapy genspider example example.com,第三个词是spider的名称,后面是网站的域名。如图:

webp


以上部分是关于scrapy虚拟环境的搭建,以及如何通过命令来新建一个scrapy工程。

在pycharm打开article_spider项目之后,需要导入之前创建的虚拟环境,即配置解释器。项目默认的是python3环境的python.exe,但是如果你创建了虚拟环境,虚拟环境的文件夹的scripts文件夹下也有python.exe。

webp


3.4 启动spider的两种方法

  1. 启动一个spider的命令是scrapy crawl spider名称,运行命令尝试一下是否能正确启动jobbole这个spider,出现如下情况,解决好安装完成win32包之后就能正常启动了。启动sipder报错No module named "Win32api"解决办法如下“:

    webp

  1. 但是我们要在pycharm中完成爬虫,而不是每次都打开命令行,因此编写mian.py文件(放在主项目下),来调用spider命令。右键运行这个文件就可以啦。

# pycharm里面没有关于scrapy的模板,所以是没法直接调试的,需要自己手动编写一个main文件# 在这个文件中调用命令行,就可以完成调试了from scrapy.cmdline import execute# 调用这个函数可以执行scrapy的脚本import sysimport os# print(os.path.dirname(os.path.abspath(__file__)))sys.path.append(os.path.dirname(os.path.abspath(__file__)))# os.path.dirname(os.path.abspath(__file__)) 获取main文件路径的父目录# os.path.abspath(__file__) 获取当前main文件的路径# 需要设置工程的目录,必须在项目所在的目录下运行,再调用执行命令才会生效# sys.path.append("D:\PycharmProjects\ArticleSpider") 如果路径设置死了,一旦项目位置发生变动,就需要改动很麻烦execute(["scrapy","crawl","jobbole"])# 调用execute()函数来执行spider命令,传入数组,即是执行启动spider的命令# 一运行这个文件,如果在jobbole.py中parse()函数处设置断点,可以发现能够正常启动,并且返回了相关response变量# 点开这个变量可以查看到,访问了某个网址,并且正常响应,也得到了body网页内容# 下一步就是对其中的内容进行解析,获取想要爬取的内容啦。



作者:田同学的小迷妹儿
链接:https://www.jianshu.com/p/c8b1944d2924


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP