您的位置:首页 > 其它

入门爬虫基础知识

2019-01-28 11:56 435 查看

通常网络通信客户端发起请求(请求报文),服务端进行响应;爬虫简单来讲就是仿造一个客户端请求去获取服务端的响应,将获得的文档使用正则表达式等方法解析出来,从而得到我们所需要的数据等信息。关于请求报文详细格式可以参考下面链接的末尾介绍:https://blog.csdn.net/weixin_43750685/article/details/84329588
Scrapy介绍:https://yiyibooks.cn/zomin/Scrapy15/index.html

一、urllib模块

1.urllib是由URL和lib两个单词共同构成的;URL就是常说的网址;lib是library(库)的缩写。
URL由三部分组成
1)协议,常见的有http、https、ftp、file、ed2k等等;
2)存放资源的服务器的域名系统(DNS)主机名或IP地址(有时候包含端口号,各种传输协议都有端口,入http协议默认端口号为80)
3)主机资源的具体地址,如目录和文件名等。
PS:第一部分和第2部分用“://”符号隔开;第2部分和第3部分用“/”符号隔开;第1部分和第2部分是不可缺少的,第3部分有时可以省略。

2.urllib实际是一个Python package,即是一个包,里边总共有四个模块module,分别是:urllib.request、urllib.error、urllib.parse、urllib.robotparse;第一个模块(request)是最复杂的也是最重要的,因为它包含了对服务器请求的发出、跳转、代理和安全等各个方面。通过urllib.request.urlopen()函数就可以访问网页。
1)urlopen实际上返回的是一个类文件对象,因此你可以用read()方法来读取内容;
2)对urlopen()函数返回的文件对象可能还会用到的函数有:
· geturl(),返回请求的url;
· info(),返回一个http.HTTPMessage对象,包含远程服务器返回的头信息;
· getcode(),返回HTTP状态码。
PS:
res = urllib.request.Request(‘https://www.baidu.com/’)
response = urllib.request.urlopen(res)
url_new = response.geturl()
print(url_new)
info_new = response.info()
print(info_new)
code_new = response.getcode()
print(code_new)
3)josn模块(JSON是一种轻量级的数据交换格式)

Request网络请求

通常客户端和服务器之间进行请求-响应时,两种最长被用到的方法是GET和POST;通常GET是从指定服务器请求数据,POST是向指定服务器提交要被处理的数据(当然这不是绝对的,GET有时也会用来提交要被处理的数据给服务器)

Request URL:https://oimageb2.ydstatic.com/image?id=-8696510948471586968&product=xue
#请求的链接地址
Request Method:GET
#请求的方法,这里是GET
Status Code:304 Not Modified
#状态码,304表示重定向
Remote Address:36.102.230.145:443
#服务器IP地址和端口号
1.Request Header是客户端发送的请求的Header。
Python如何提交POST表单呢?
1)urlopen()函数有一个data参数,如果给参数赋值,那么HTTP的请求就是使用的POST方式;如果data参数的值是NULL,也就是默认值,那么HTTP的请求就是GET方式。

BeautifulSoup()函数用法

from bs4 import BeautifulSoup
案例一:编写一个爬虫,爬取百度百科“网络爬虫”的词条(网址 https://baike.baidu.com/item/网络爬虫),并将所有包含“item”关键字的链接按格式打印出来。
BeautifulSoup()是用于从HTML或者XML文件中提取数据,所以需要先使用urllib.request模块从指定网址上线读取HTML文件:

BeautifulSoup(html, ‘html.parser’)需要两个参数,第一个参数是需要提取数据的HTML或XML文件;第二个参数是指定解析器,然后使用find_all(href=re.compile(‘item’))方法编译正则表达式可以读取所有包含“item”关键字的链接。

爬虫异常处理

1.URLError异常:


PS:注意urllib.error模块的调用 (error只是个模块,因此判断URLError 和HTTPError异常时要通过模块去调用,即urllib.error.URLError | urllib.error.HTTPError)

2.HTTPError异常(用法与URLError类似)

HTTPError是URLError的子类,服务器上每一个HTTP响应都包含一个数字的“状态码”。有时候状态码会指出服务器无法完成的请求类型,一般情况下Python会帮你处理一部分这类响应;但是呢,有一些无法处理,就会抛出HTTPError异常。这些异常包括典型的404(页面无法找到)、403(请求禁止)、401(验证请求)。
因为Python默认会自动帮你处理重定向方面的内容(状态码300-399范围),状态码100-299的范围是表示成功,所以你需要关心的是400-599这个范围的状态码(应为它们代表响应出了问题)。其中,出现4XX状态码,说明问题来自客户端,就是你自己哪里做错了;出现5XX状态码,那就是来自服务器的问题。
当出现一个错误的时候,服务器返回一个HTTP错误号(即400-599范围内的状态码)和一个错误页面。可以使用HTTPError实例作为页面返回的响应对象。它同样也是拥有像read()、geturl()、和info()这类方法。
用法

3.处理异常

处理HTTPError、URLError异常有两种方法:
1)方法一:
from urllib.request import Request,urlopen
from urllib.error import URLError,HTTPError
直接import引入异常,except时候就不用通过模块去调用异常,只是调入模块的话,except需要通过模块去调用对应异常。

PS:需要注意的是:如果要同时测试except HTTPError和except URLError异常,except HTTPError必须要写在except URLError前面,因为它是except URLError的子类,如果把except URLError放前面,就会把except HTTPError的内容过滤掉。
2)方法二:

PS:使用内置函数hasattr()和if条件分支将异常状态码和错误原因分开来写,通常处理异常比较推荐方法二写法。

Scrapy爬虫框架

1.安装scrapy

安装scrapy:直接在pycharm里面搜索第三方库scrapy进行安装,安装scrapy的时候,使用pip install scrapy一般会失败
如:pip install scrapy 时出现:
error: Microsoft Visual C++ 14.0 is required. Get it with “Microsoft Visual C++ Build Tools”: http://landinghub.visualstudio.com/visual-cpp-build-tools
解决办法
安装 Microsoft visual c++ 14.0
https://pan.baidu.com/s/1q2Nj41Xk85CHHv7_zOhQIA 密码:qbba;下载下来之后安装即可。
另外还需要再使用pycharm安装pypiwin32

使用Scrapy抓取一个网站一共需要四个步骤:
1.新建项目 (scrapy startproject xxx):新建一个新的爬虫项目
2.明确目标 (编写items.py):明确你想要抓取的目标
3.制作爬虫 (spiders/xxspider.py):制作爬虫开始爬取网页
4.存储内容 (pipelines.py):设计管道存储爬取内容
1.创建一个Scrapy项目:
可以在pycharm里面使用终端执行:E:\Python代码文档\正则表达式>scrapy startproject mySpider(自定义项目名称)
2.定义Item容器:
编辑创建的scarpy项目目录中的items.py

3.编写爬虫:
先在mySpider/spiders目录下创建一个.py文件。
创建有两种方法:
1)在spiders目录下使用pycharm右键新建一个python文件即可;
2)还可以在pycharm里面使用终端执行:E:\Python代码文档\正则表达式\mySpider\spiders>scrapy genspider itcast itcast.cn (itcast.cn为你需要爬取的网页的主域名,例如:jd.com
使用方法2,通过命令去创建可以免去编写固定代码的麻烦
使用方法1,该.py文件中的固定代码都需要手动去编写。

如上图所示:
要建立一个Spider, 你必须用scrapy.Spider类创建一个子类,并确定了三个强制的属性 和 一个方法。
1.name = “” :这个爬虫的识别名称,必须是唯一的,在不同的爬虫必须定义不同的名字。
2.allow_domains = [] 是搜索的域名范围,也就是爬虫的约束区域,规定爬虫只爬取这个域名下的网页,不存在的URL会被忽略。
3.start_urls = () :爬取的URL元祖/列表。爬虫从这里开始抓取数据,所以,第一次下载的数据将会从这些urls开始。其他子URL将会从这些起始URL中继承性生成。
4.parse(self, response) :解析的方法,每个初始URL完成下载后将被调用,调用的时候传入从每一个URL传回的Response对象来作为唯一参数,主要作用如下:
负责解析返回的网页数据(response.body),提取结构化数据(生成item)
生成需要下一页的URL请求。
将start_urls的值修改为需要爬取的第一个url
start_urls = (“http://www.itcast.cn/channel/teacher.shtml”,)
5.修改parse()方法:如上图所示内容def parse(self, rsponse)

6.爬虫编写好之后,准备就绪,然后运行一下看看,在mySpider目录下执行:

E:\Python代码文档\正则表达式\mySpider>scrapy crawl itcast
(执行scrapy crawl itcast可能会报错误,提示没有pypiwin32,这时使用pycharm安装一个pypiwin32即可)
如果打印的日志出现 [scrapy] INFO: Spider closed (finished),代表执行完成。 之后当前文件夹中就出现了一个 teacher.html 文件,里面就是我们刚刚要爬取的网页的全部源代码信息。

爬取整个网页完毕,接下来的就是提取过程了
提取数据之前需要先启动scrapy shell,启动方式为在scrapy根目录启动:E:\Python代码文档\正则表达式\mySpider>scrapy shell “http://www.itcast.cn/channel/teacher.shtml” (该链接即为你爬取的网页)

在使用scrapy框架做爬虫时,有两种方式对标签内容进行提取:css和Xpath。基本的标签内容,属性提取都很容易。但对于多层嵌套的标签,如何提取到最里层的内容呢?
举个栗子:
网页HTML内容是:
“helloworld!


如何一下子提取到hello world!呢?
用css的话需要写两次选择:
response.css(’#test::text’).extract_first()
response.css(’#test b::text’).extract_first()
这个简单的例子还似乎可以这样做,但是实际项目中可没这么简单,往往是整篇文章都是嵌套的段落,文字,外面是p便签,里面是多层span标签,而且个数还不一致,根本无法一个个写。。。
因此,需要一种一次性提取最里层内容的方法!

用Xpath可以做到:
不了解Xpath的话可以参考W3C教程:https://www.w3cschool.cn/xpath/

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: