Python分布爬虫——爬虫前奏和网络请求

前言

继续python的学习,这次学习爬虫,听说比较好玩,我也学学。

爬虫前奏

什么是网络爬虫?

  1. 爬虫的实际例子:
  • 搜索引擎(百度、谷歌、360搜索等)
  • 数据分析与研究
  • 抢票软件等
  1. 什么是网络爬虫
  • 通俗理解:爬虫是一个模拟人类请求网站行为的程序,可以自动请求网页,并将数据提取下来,然后使用一定的规则提取有价值的数据。
  • 专业介绍:🍗百度百科🍖维基百科
  1. 通用爬虫和聚焦爬虫
  • 通用爬虫:通用爬虫是搜索引擎提取系统(百度等)的重要组成部分。主要是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份。
  • 聚焦爬虫:是面向特定需求的一种网络爬虫程序,他与通用爬虫的区别就在于:聚焦爬虫在实践网页抓取的时候会对内容进行筛选和处理,尽量保证只抓取与需求相关的网页信息。
  1. 大部分语言基本上都可以来写爬虫,但是python有它独特的优点。

网络请求

urlopen函数用法

urllib库是python中最基本的网络请求库。可以模仿浏览器的行为,向指定的服务器发送一个请求,并可以保存服务器返回的数据。

在Python3的urllib库中,所有和网络请求相关的方法,都被集成到urllib.request模块下面了。基本使用栗子:

from urllib import request
resp = request.urlopen("http://www.baidu.com")
print(resp.read())

m0re
实际上,使用浏览器访问百度,右键查看源代码,会发现,跟上面打印的数据是一样的。也就是说上面三行代码已经帮我将百度首页的全部代码爬下来了。
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')

m0re
这个就是爬取下来的baidu页面
还可以爬取图片
随便找张图片,复制它的地址,然后修改参数,进行爬取
m0re
这是一张鲁班的图片,成功爬取下来了。

参数解码和解码函数

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

还可以这么做
m0re
parse_qs函数可以将urlencode函数编码过的字符串进行解码
如下
m0re

urlparseurlsplit

有时候拿到一个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)

m0re
urlparseurlsplit基本上是一模一样的,唯一不一样的地方是,urlparse里面多了一个params属性,而urlsplit没有这个属性。比如有一个URLhttp://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())

可以看出也是可以爬取到的
m0re
然后要记一点就是不加User-Agent的话,爬虫进行爬取的话,是不会得到有用的信息的,可以将上面的代码中的user-Agent去掉试试,如果不加User-Agent网站会轻易的识别出来爬虫,然后不给它爬取有用的信息。

到那时有些信息是需要爬取js代码才能得到的。比如爬取某网站的职位招聘信息。
先找到需要爬取的网站的以下信息:
m0re
首先找到信息所在的网页,查看请求的URL和请求方式

其次就是data数据
m0re
写入代码中去,模仿浏览器访问网页以达到爬取信息的目的

#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
    m0re
    尽量选择一个最后验证时间比较近的。
    代码示例:
#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
配置问题,不细说了。
m0re
下面挂几个常用的代理,如需更多请百度。
常用的代理有:

  • 快代理: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,加入到爬虫脚本中去。
m0re
添加到headers中,然后进行爬取。
以人人网为例。人人网中,要访问用户的主页进行浏览信息,需要登录才可以,也就是要有cookie信息,如果想用代码的方式访问,就需要有正确的cookie信息才能访问,解决方法有两种:第一种是使用浏览器访问,然后将cookie信息复制下来,放到headers中。(没有账号,懒得注册了)缺点是每次访问都需要从浏览器复制cookie,麻烦。在Python处理Cookie,一般是通过http.cookiejar模块和urllib模块的HTTPCookieProcessor处理器类一起使用。http.cookiejar模块的作用是提供用于存储cookie的对象。而HTTPCookieProcessor处理器主要作用是处理这些cookie对象,并构建handler对象。

爬虫自动登录访问授权页面

http.cookiejar模块
该模块主要的类有:CookieJar、FileCookieJar、MozillaCookieJar、LWPCookieJar。这四个类的作用分别如下

  1. CookieJar:管理HTTP cookie值、存储HTTP请求生成的cookie、向传出的HTTP请求添加cookie的对象。整个cookie都存储在内存中,对CookieJar实例进行垃圾回收后cookie也将丢失。
  2. FileCookieJar:从CookieJar派生而来,用来创建FileCookieJar实例,检索cookie信息并将cookie存储到文件中。filename是存储cookie的文件名。delayload为True时支持延迟访问文件,即只有在需要时才读取文件或在文件中存储数据。
  3. MozillaCookieJar:从FileCookieJar派生而来,创建与Mozilla浏览器cookie.txt兼容的FileCookieJar实例。
  4. LWPCookieJar:从FileCookieJar派生而来,创建与libwww-per标准的Set-Cookie3文件格式兼容的FileCookieJar实例。

先学习到这里,需要消化一下,下次继续学习这个部分——利用爬虫登录登陆访问。

posted @ 2020-07-18 15:37  m0re  阅读(79)  评论(0编辑  收藏  举报