页面结构的简单认识
如图是我们在pycharm中创建一个HTML文件后所看到的内容
这里我们需要认识的是上图的代码结构,即html标签包含了head标签与body标签
table标签
table标签代表了一个网页页面中的表格,其包含了行和列,其中行标签我们使用tr标签,在行中我们可以定义列,列我们使用的是td标签
如图我们在body标签中 编写了上图代码,即定义了一个一行三列的表格
在浏览器中运行可以看到
如果想要表格的结构更明确,我们可以这样
ul标签
ul标签代表的是网页中的无序列表,我们可以往列表中添加我们想要的元素,这些元素我们使用li标签进行定义
ol标签
ol标签代表的是网页中的有序列表,其中的元素也是使用li标签定义
a标签
a标签代表的是网页中的超链接,即点击后可以进行页面的跳转,我们使用href属性指定想要的跳转到的域名
点击即跳转到百度
爬虫概念理解
我们一般有以下两种理解
- 通过一个程序,根据url进行爬取网页,获取有用信息
- 使用程序模拟浏览器,去向服务器发送请求,获取相应信息
爬虫核心
- 爬取网页:爬取整个网页,包含了网页中所有的内容
- 解析数据:将你得到的数据进行解析
- 难点:爬虫与反爬虫之间的博弈
urllib库使用
urllib是python自带的库,我们可以直接使用,无需下载,下面演示使用urllib爬取baidu首页源码
先导入该库
再使用urlopen()函数去向参数url发出请求,返回值为服务器的响应对象 ,其中包含了关于该网页的内容,也包括源码,我们使用read()方法即可得到源码,但是注意得到的是二进制形式的数据,因此我们需要将其解码,这里使用编码为utf8的decode()方法进行解码
再打印出解码后的数据即可
一个类型与六个方法
- 一个类型即我们上面样例中urlopen()的返回值为HTTPResponse类型
六个方法如下:
将爬取到的网页、图片、视频下载到本地
这里主要使用的函数是urlretrieve(参数1,参数2)
其中参数1是需要下载的对象地址,参数2是想要下载到的本地位置,上图中我没有指定位置,因此直接下载到的该python文件的目录下
反爬手段User-Agent
User Agent中文名为用户代理,简称 UA。
它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等等。
也就是说,假设:一个平台,设置了UA权限,必须以浏览器进行访问
当你使用爬虫脚本去访问该网站的时候,就会出现,访问失败、没有权限 、或者没有任何资源返回的结果等错误信息。
那么我们应该如何克服它呢??
我们需要在爬虫时添加一个User-Agent请求头即可
具体怎么做呢?
如上图所示,我们在爬取协议为https的百度首页时发现得到的源码很少,就是遇到了反爬手段UA
下面是对url知识的补充
好了继续解决UA
如上,我们在最下面可以看到我们的UA
我们将其复制下来,在代码中存储为一个字典,然后使用Request得到一个带有UA的请求头的url,然后按照前面所学即可爬取内容啦
需要强调的是,这里因为Request()方法的参数第二个参数并非headers因此我们需要使用关键字传参
get请求的quote方法
在前面我们在代码中输入一个url时,我们可能会输入包含有中文字符的url
例如
此时如果我们直接就这样按照前面所学去爬取该域名内的源码,会出现编码报错问题,因此我们需要将“周杰伦”进行编码,这里就使用到了urllib.parse.quote()方法,该方法可以将中文字符编码为Unicode,再将其拼接到我们将被输入的url上即可
get请求的urlencode()方法
有时候我们会需要将多个参数拼接到我们的url上,但是此时再去使用quote方法便会变得麻烦,因此就有了urlencode方法,它用于拼接多个参数的url
如下我们将我们需要的参数wd与sex与location拼接到了我们的url上同时实现了爬虫
post请求
post是相对于前面所学的get请求的另外一种请求,二者的区别在于post请求的url参数并不是直接拼接在url后面的,而是在进行 请求对象的定制中 进行传参赋值
下面通过百度翻译例子进行解析
在百度翻译中输入python进行翻译后刷新,其实不难发现,页面上马上就发生了改变,其实这是浏览器快速对服务器进行了请求,我们通过查看这些请求,发现上图中该请求实现了翻译
在获取到该请求的url地址后,我们希望将kw参数传给它
正如上面所说,我们在进行请求对象定制的时候将参数data传给了url,这里需要注意的是data在作为参数传递时必须是编码后的形式,而urlencode得到的是字符串类型是不能直接作为data传给Request的,因此需要encode('utf-8')
反爬手段之header
有时候请求头中仅仅包含UA是不够的,我们需要得到更多的请求头参数
样例演示(爬取百度翻译的详细翻译):
首先在百度翻译的网络请求中找到下面这一条
再得到它的URL
得到对应参数
写入代码
然后按照前面所学的进行爬虫即可
得到结果如下:
我们发现这与我们想要的结果并不同
这是因为网站有另外一种反爬虫手段,即header参数要求更多
我们只需在网站上的请求头所有参数给到 对象的定制里面即可
再次运行 即可
将json文件下载到本地
样例演示(豆瓣动作电影排行榜第一页的爬取)
首先需要找到有效的网络请求
得到对应的URL及其UA
输入代码
需要注意的是这里对于open方法默认是使用gbk编码,我们需要传参时指定为utf-8
如果想要爬取多页数据我们则需要观察网络请求中每一页请求的url
还是上面的例子
我们在找到前三页的网络请求便很容易得到其中的规律
然后遍历我们想要的页数 ,得到对应的url,循环前面的操作即可
多页数据的post爬取
在面对爬取多页数据的需求上,还是一样的步骤
- 在网络请求中找到页面数据的那个请求,对比每一页的请求的URL,找到规律
- 循环遍历每一页,对每一页操作即可
我们观察发现因为网页时post类型的,所以参数并没有直接包含在URL里,因此需要到payload中寻找
对比多页数据不难发现其规律,即每一页的页码即参数中的pageIndex
因此我们循环遍历页数page,每次构建对象的定制时传入对应的page,然后后续按照post的爬虫步骤来即可
urllib中的异常
主要包含以下两类
- URLError
- HTTPError该异常时URLRError的子类
它们都属于urllib.error这个包
其中http异常可能是针对浏览器无法链接到服务器所产生的错误提示
url异常则可能是主机名上出现的错误
我们都可以采用try-except对上述两类异常进行捕获
cookie登录
只要我们拥有某个需要登录才能进入的页面的cookie,我们就可以爬进这个页面,就可以携带者cookie进入到任何页面
因为cookie中包含着登录信息
此外还有一个header参数referer是用来制作图片的防盗链的,即它会判断当前路径是不是由上一个路径进来的
因此如果想要进入一些需要登陆才能进入的页面则一般需要上面两个header参数
Handler处理器
随着业务逻辑的复杂,请求对象的定制已经满足不了我们的需求,例如动态cookie和代理不能仅仅使用urlopen()函数来解决
因此这里提出Handler处理器来处理一些复杂的需求
基本步骤如下:
- 获取Handler对象
- 获取opener对象
- 调用open方法
如上图所示,我们使用Handler来爬取百度首页的源码
代理服务器
我们还可以使用代理IP来实现爬虫
- 代理可以帮助我们突破自身IP限制,访问国外站点
- 访问一些单位或团体内部资源
- 提高访问速度
- 隐藏自身真实IP
具体实现步骤如下:
- 创建request对象
- 创建ProxyHandler对象
- 使用handler对象创建opener对象
- 使用opener.open()函数发送请求
实际上步骤与前面所学类似的,只不过这里使用的是ProxyHandler函数来创建一个handler对象,之后步骤与前面所学一致
scrapy
什么是scrapy?
Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,可以应用在包括数据挖掘,信息处理或存储历史数据等一系列程序中
安装scrapy
pip install scrapy
创建爬虫的项目
scrapy startproject 项目的名字
注意:项目的名字不能以数字开头且不能包含中文
项目结构具体如下:
创建爬虫文件
要在spiders文件夹中去创建爬虫文件
scrapy genspider 爬虫文件的名字 要爬取的网页
运行爬虫代码
scrapy crawl 爬虫的名字