Python分布爬虫——爬虫前奏和网络请求
本文目录
前言
继续python的学习,这次学习爬虫,听说比较好玩,我也学学。
爬虫前奏
什么是网络爬虫?
- 爬虫的实际例子:
- 搜索引擎(百度、谷歌、360搜索等)
- 数据分析与研究
- 抢票软件等
- 什么是网络爬虫
- 通用爬虫和聚焦爬虫
- 通用爬虫:通用爬虫是搜索引擎提取系统(百度等)的重要组成部分。主要是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份。
- 聚焦爬虫:是面向特定需求的一种网络爬虫程序,他与通用爬虫的区别就在于:聚焦爬虫在实践网页抓取的时候会对内容进行筛选和处理,尽量保证只抓取与需求相关的网页信息。
- 大部分语言基本上都可以来写爬虫,但是python有它独特的优点。
网络请求
urlopen函数用法
urllib库是python中最基本的网络请求库。可以模仿浏览器的行为,向指定的服务器发送一个请求,并可以保存服务器返回的数据。
在Python3的urllib库中,所有和网络请求相关的方法,都被集成到urllib.request
模块下面了。基本使用栗子:
from urllib import request
resp = request.urlopen("http://www.baidu.com")
print(resp.read())
实际上,使用浏览器访问百度,右键查看源代码,会发现,跟上面打印的数据是一样的。也就是说上面三行代码已经帮我将百度首页的全部代码爬下来了。
urlopen
函数的详细介绍:
url: 请求的url
data: 请求的data,如果设置了这个值,那么将变成post请求。
返回值: 返回值是一个http.client.HTTPResponse对象,这个对象是一个类文件句柄对象。有read(size)、 readline、 readlines以及getcode等方法。
getcode就是获取当前响应的这个状态码。
urlretrieve函数用法
这个函数可以方便的将网页上的一个文件保存到本地,以下代码可以非常方便的将百度的首页下载到本地:
from urllib import request
request.urlretrieve('http://www.baidu.com/','baidu.html')
这个就是爬取下来的baidu页面
还可以爬取图片
随便找张图片,复制它的地址,然后修改参数,进行爬取
这是一张鲁班的图片,成功爬取下来了。
参数解码和解码函数
urlencode
函数
用浏览器发送请求的时候,如果URL中包含了中文或者其他特殊字符,那么浏览器会自动的给它进行编码。而如果使用代码发送请求,那么就必须手动的进行编码,这个时候就应该使用urlencode
函数来实现。urlencode
可以把字典数据转换为URL编码的数据。示例代码如下
from urllib import parse
data = {'name':'m0re',"age":18,'great':'hello,world'}
j4y = parse.urlencode(data)
print(j4y)
结果:
name=m0re&age=18&great=hello%2Cworld
还可以这么做
parse_qs
函数可以将urlencode函数编码过的字符串进行解码
如下
urlparse
和urlsplit
有时候拿到一个URL,想要对这个URL中的各个组成部分进行分割,那么这个时候就可以使用urlparse
或者是urlsplit
来进行分割。示例代码如下:
#encoding: utf-8
from urllib import request,parse
url = 'http://www.baidu.com/s?username=zhiliao'
result = parse.urlsplit(url)
print('scheme',result.scheme)
print('netloc',result.netloc)
print('path',result.path)
print('query',result.query)
urlparse
和urlsplit
基本上是一模一样的,唯一不一样的地方是,urlparse
里面多了一个params
属性,而urlsplit
没有这个属性。比如有一个URL
为http://www.baidu.com/s;hello?wd=python&username=abc#1
,那么urlparse
可以获取到hello
,而urlsplit
不可以获取到。但是url
中的params
也用的比较少。
Request类
如果想要在请求的时候增加一些请求头,那么必须使用request.Request
类来实现。比如要增加一个User-Agent
,示例代码
#encoding: utf-8
from urllib import request
url = 'https://www.xxxxxx.com/zhaopin/Python/?labelWords=label'
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36'}
req = request.Request(url,headers=headers)
resp = request.urlopen(req)
print(resp.readlines())
可以看出也是可以爬取到的
然后要记一点就是不加User-Agent
的话,爬虫进行爬取的话,是不会得到有用的信息的,可以将上面的代码中的user-Agent
去掉试试,如果不加User-Agent
网站会轻易的识别出来爬虫,然后不给它爬取有用的信息。
到那时有些信息是需要爬取js代码才能得到的。比如爬取某网站的职位招聘信息。
先找到需要爬取的网站的以下信息:
首先找到信息所在的网页,查看请求的URL和请求方式
其次就是data数据
写入代码中去,模仿浏览器访问网页以达到爬取信息的目的
#encoding: utf-8
from urllib import request,parse
#url = 'https://www.xxxxx.com/jobs/list_python?labelWords=&fromSearch=true&suginput='
#resp = request.urlopen(url)
#print(resp.read())
url = 'https://www.xxxxxx.com/jobs/positionAjax.json?px=default&city=%E5%8C%97%E4%BA%AC&needAddtionalResult=false'
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36' }
data = {
'first': 'true',
'pn': 1,
'kd': 'python'
}
req = request.Request(url, headers=headers, data=parse.urlencode(data).encode('utf-8'), method='POST')
resp = request.urlopen(req)
print(resp.read())
爬取某招聘网站的职位信息,。这样已经是初步模型了,但是爬取不到信息,因为目前大多数网站都有反爬机制,所以报出了这样一个错误,其实也不是错误,就是浏览器返回的信息
b'{"status":false,"msg":"\xe6\x82\xa8\xe6\x93\x8d\xe4\xbd\x9c\xe5\xa4\xaa\xe9\xa2\x91\xe7\xb9\x81,\xe8\xaf\xb7\xe7\xa8\x8d\xe5\x90\x8e\xe5\x86\x8d\xe8\xae\xbf\xe9\x97\xae","clientIp":"42.226.97.244","state":2402}\n'
这是经过URL编码的,解码一下就是访问的过于频繁,让我们稍后再访问。但是再回到浏览器中访问是完全没有问题的。
原因就是反爬虫机制的作用。还是能轻易检查出来我的爬虫,需要模仿的再像一点。加个Referer(同样是去浏览器的开发者界面寻找)
有些网站的反爬虫机制比较强,可能加了Referer还是爬取不到有用的信息。
需要再进行深层次的学习,添加其他验证身份的条件,比如下面将要学习的Cookie。
ProxyHandler处理器(代理设置)
很多网站会检测某一段时间某个IP的访问次数(通过流量统计,系统日志等),如果访问次数多的不像正常人,它会禁止这个IP访问。所以应对方法是设置一些代理服务器,每隔一段时间换一个代理,就算IP地址被禁止,依然可以换个IP继续爬取。
urllib
中通过ProxyHandler
来设置代理服务器。
前提:
- http://httpbin.org/这个都可以访问的。这个网站可以方便的查看http请求的一些参数
- 一个代理IP
尽量选择一个最后验证时间比较近的。
代码示例:
#encoding: utf-8
from urllib import request
url = "http://httpbin.org/ip"
# 传入代理
handler = request.ProxyHandler({"http":"49.70.89.14:9999"})
# 使用上面创建的handler构建一个opener
opener = request.build_opener(handler)
# 使用opener去发送一个请求
resp = opener.open(url)
print(resp.read())
-
使用
urllib.request.ProxyHandler
传入一个代理,这个代理是一个字典,字典的key依赖于代理服务器能够接收的类型,一般是http
或者https
-
使用上一步创建的
headler
,以及request.build_opener
创建一个opener
对象 -
使用上一步创建的
opener
,调用open
函数,发起请求
注意:
代理需要自己设置有用的代理,我这个只是个免费的,现在可以,不知道明天还行不行,就这样。
然后各种报错,emmm,代码没问题,就是配置的问题了
报错一:
urllib.error.URLError: <urlopen error [Errno 11001] getaddrinfo failed>
这个与请求的URL有关,解决办法就是,把请求的URL原本是单引号包着的,改成双引号就OK了。(上面的代码已经修改)
报错二:
urllib.error.URLError: <urlopen error [WinError 10061] 由于目标计算机积极拒绝,无法连接。>
这个百度就有,但是有的解决不了,是电脑配置的原因。
可参考
https://bbs.csdn.net/topics/392282730?list=lz
http://www.manongjc.com/article/113971.html
配置问题,不细说了。
下面挂几个常用的代理,如需更多请百度。
常用的代理有:
- 快代理:http://www.kuaidaili.com/
- http://www.goubanjia.com/
- http://www.66ip.cn/1.html
- http://www.ip3366.net/free/
- http://www.kxdaili.com/dailiip.html
- https://www.kuaidaili.com/free/
- https://www.xicidaili.com/
- http://www.iphai.com/
- http://www.89ip.cn/
- http://www.proxy360.cn/Region/China
- http://www.ip181.com/
- https://premproxy.com/
- http://www.xroxy.com/
- http://www.data5u.com/free/
Cookie模拟登陆
在浏览器中寻找到cookie,加入到爬虫脚本中去。
添加到headers中,然后进行爬取。
以人人网为例。人人网中,要访问用户的主页进行浏览信息,需要登录才可以,也就是要有cookie信息,如果想用代码的方式访问,就需要有正确的cookie信息才能访问,解决方法有两种:第一种是使用浏览器访问,然后将cookie信息复制下来,放到headers中。(没有账号,懒得注册了)缺点是每次访问都需要从浏览器复制cookie,麻烦。在Python处理Cookie,一般是通过http.cookiejar
模块和urllib
模块的HTTPCookieProcessor
处理器类一起使用。http.cookiejar
模块的作用是提供用于存储cookie的对象。而HTTPCookieProcessor
处理器主要作用是处理这些cookie对象,并构建handler对象。
爬虫自动登录访问授权页面
http.cookiejar
模块
该模块主要的类有:CookieJar、FileCookieJar、MozillaCookieJar、LWPCookieJar。这四个类的作用分别如下
CookieJar
:管理HTTP cookie值、存储HTTP请求生成的cookie、向传出的HTTP请求添加cookie的对象。整个cookie都存储在内存中,对CookieJar实例进行垃圾回收后cookie也将丢失。FileCookieJar
:从CookieJar
派生而来,用来创建FileCookieJar
实例,检索cookie信息并将cookie存储到文件中。filename
是存储cookie的文件名。delayload
为True时支持延迟访问文件,即只有在需要时才读取文件或在文件中存储数据。MozillaCookieJar
:从FileCookieJar
派生而来,创建与Mozilla浏览器cookie.txt兼容的FileCookieJar
实例。LWPCookieJar
:从FileCookieJar
派生而来,创建与libwww-per标准的Set-Cookie3文件格式兼容的FileCookieJar
实例。
先学习到这里,需要消化一下,下次继续学习这个部分——利用爬虫登录登陆访问。