这节我们开设新的模块,也就是爬虫基础知识讲解,大家如果没学过python、前端基本知识请参考小白基础模块。接下来我们先来了解一下网络爬虫的工作过程
1 网络爬虫工作过程
以通用爬虫为例,如果不知道什么是通用爬虫去小白基础篇第一节学习。
第一步我们先找到自己想要获取数据的地址路径也就是URL
第二步将URL放入待抓取URL队列
第三步读取待抓取URL队列中的URL,解析它的DNS,并且得到服务器的IP,将URL对应的网页下载下来,存储进已下载网页库中。此外,将这些URL放进已抓取 URL 队列。
第四步分析已抓取 URL 队列中的 URL,从已下载的网页数据中分析出其他 URL,并和已抓取的 URL 进行比较去重,最后将去重过的 URL 放入待抓取 URL 队列,从而进入下一个循环。
如图为通用爬虫的工作流程
接下来我们来介绍一下如何读取URL,下载网页等操作,python3实现HTTP请求的两种方式分别是urllib库和requests库来实现。这里我们今天先介绍urllib库。
2.什么是urllib库呢?
Urllib 库是 Python 中的一个功能强大、用于操作 URL,并在做爬虫的时候经常要用到的库。在 Python2.X 中,分 Urllib 库和 Urllib2 库,Python3.X 之后合并到 Urllib 库中,使用方法稍有不同,如下
在 Python2.X 中使用 import urllib2——对应的,在 Python3.X 中会使用 import urllib.request,urllib.error。
在 Python2.X 中使用 import urllib——对应的,在 Python3.X 中会使用 import urllib.request,urllib.error,urllib.parse。
在 Python2.X 中使用 import urlparse——对应的,在 Python3.X 中会使用 import urllib.parse。
在 Python2.X 中使用 import urllib2——对应的,在 Python3.X 中会使用 import urllib.request,urllib.error
在 Python2.X 中使用 urllib2.urlopen——对应的,在 Python3.X 中会使用 urllib.request.urlopen。
在 Python2.X 中使用 urllib.urlencode——对应的,在 Python3.X 中会使用 urllib.parse.urlencode。
在 Python2.X 中使用 urllib.quote——对应的,在 Python3.X 中会使用 urllib.request.quote。
在 Python2.X 中使用 cookielib.CookieJar——对应的,在 Python3.X 中会使用 http.CookieJar。
在 Python2.X 中使用 urllib2.Request——对应的,在 Python3.X 中会使用 urllib.request.Request。
遇到以上问题记得改过来就行一般问题不大。下面我们就以python3.X为例。
首先介绍一下urllib的函数模块
urlopen函数:
在Python3的urllib库中,所有和网络请求相关的方法,都被集到urllib.request模块下面了,以先来看下urlopen函数基本的使用源代码:
from urllib import request
resp = request.urlopen('http://www.zhihu.com')
html = str(resp.read(),'utf-8')
print(html)
在urlopen当中一般传入两个参数
1.url地址
2.data,如果传入这个值那么变成post请求
3.返回值:返回值是一个http.client.HTTPResponse对象,这个对象是一个类文件句柄对象。有read(size)、readline(返回一行数据)、readlines以及getcode等方法。
Read与readlines两者都是返回所有数据,但是read是会将值返回给字符串而readlines将值返回给列表
下面我们可以把爬取到的数据保存到html文件中,这样就能成为本地网页
from urllib import request
resp = request.urlopen('http://www.zhihu.com')
html = resp.read()
zhihu = open('知乎.html','wb')
zhihu.write(html)
zhihu.close()
print(html)
如图生成了知乎.html文件
打开来看
点击chrome浏览器打开,这就是没有CSS、与JavaScript文件的结果
或者还可以通过这个urlretrieve函数
这个函数可以方便的将网页上的一个文件保存到本地。以下代码可以非常方便的将知乎的首页下载到本地—两行代码直接搞定:
from urllib import request
request.urlretrieve('http://www.zhihu.com/','zhihu.html')
效果相同~
在介绍下一个函数之前我们先来看一组案例假如我们想在百度上搜索关键字如图查看url,你会发现其实只有前面”/s?Wd=爬虫”是需要的,而后面我们去掉没有任何问题。
下面这个函数就是通过再发送请求的时候如何利用爬虫来写关键字
urlencode函数
用浏览器发送请求的时候,如果url中包含了中文或者其他特殊字符,那么浏览器会自动的给我们进行编码。而如果使用代码发送请求,那么就必须手动的进行编码,这时候就应该使用urlencode函数来实现。urlencode可以把字典数据转换为URL编码的数据。示例代码如下:
from urllib import parse
data = {'wd':'爬虫之道'}
qs = parse.urlencode(data)
print(qs)
我们可以看到上面的爬虫之道已经经过编码了,下面有一个函数可以将其解码,
parse_qs函数:
可以将经过编码后的url参数进行解码。我们把刚才输出的编码传入parse_qs函数,完成解码
from urllib import parse
qs = "wd=%E7%88%AC%E8%99%AB%E4%B9%8B%E9%81%93"
print(parse.parse_qs(qs))
现在我们来将这两种操作应用到实际应用当中我们在之前介绍urlretrieve函数内修改如下代码
from urllib import request
from urllib import parse
data = {'wd':'爬虫之道'}
qs = parse.urlencode(data)
request.urlretrieve('http://www.baidu.com/s?'+qs,'baidupach.html')
可以看到已经生成了百度搜索”爬虫之道”的文件
效果如下
爬虫小课堂:
使用爬虫来伪装浏览器访问知乎
在这节课我们最后学的就是request函数,使用它来模拟登录。在登录之前教大家如何传入浏览器信息
为啥要传入浏览器信息呢?
答案很简单伪装成浏览器—,大部分网站都会检测浏览器信息来判断用户是否为非常规操作(如网络爬虫),如果不设置浏览器信息很容易就被识破–。
怎么伪装成浏览器呢?
很简单加入请求头还有请求来源。想要在请求的时候增加一些请求头与请求来源,那么就必须使用request.Request类来实现。增加三个信息User-Agent和referer还有Cookie,其中user-agent对应着浏览器信息,referer对应着请求来源,cookie对应着Cookie(以前介绍过哈)–,那么去哪里找User-Agent和referer和Cookie呢
示例代码如下:
from urllib import request
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36',
'referer':'https://baike.baidu.com/item/%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB/5162711?fr=aladdin',
'cookie':'_zap=57a22e9e-5025-4c61-ad74-cc7044596b12; _xsrf=joWOt4nLmcLDlyP9xaF8uMBImZSCb91c; d_c0="ABDhgwX6hg6PTsoEaOvoZSDUoFBhxkkfmwo=|1542356298"; tst=r; q_c1=0e05f6de53884f68a6f04e8b9f25faac|1542356335000|1542356335000; capsion_ticket="2|1:0|10:1543740875|14:capsion_ticket|44:ODg2MjA1ZWQ5M2VlNDg2N2I0ODJkYmJhZjY2MDQxNTE=|21b07c74b4c79d0ea5319cd898a2a1db7f8651036044ebb40d1e81f86cd5ed43"; z_c0="2|1:0|10:1543740894|4:z_c0|92:Mi4xc2VUd0JRQUFBQUFBRU9HREJmcUdEaVlBQUFCZ0FsVk4zdXZ3WEFEY0EycG56eHBTbW8tRGxhT2FscmgzcktrZ0l3|b41c070f225bcfba4a0f37985079b551610988506e8f9295cf5dfbeda60c98b1"; __gads=ID=dc55a6ea526d9e81:T=1543740970:S=ALNI_MYNiFhLbq52riymclxPUW-Yo01nQg; tgw_l7_route=56f3b730f2eb8b75242a8095a22206f8'
}
req = request.Request("http://www.zhihu.com/",headers=headers)
resp = request.urlopen(req)
html = resp.read()
zhihu = open('主页.html','wb')
zhihu.write(html)
zhihu.close()
print(html)