爬虫 1
爬虫就像一个寄生虫,但它不是病毒,它可以成为我们利用的一个工具。爬虫也并不是一种很高大上的项目,每个对信息获取有需求的人都应该去了解一下网络爬虫,可以通过爬虫在法律允许的范围内获取很多必要的信息以及对信息进行分析处理。爬虫会不会很难呢?莫道南山迟,请君步行缓。一点点python基础就可以迅速入门爬虫。
搭建环境
为了能快速的进行,并且省略新手安装包、配置环境等困扰。
建议(顺序不要打乱):
使用pycharm的时候进行python项目会自动匹配Anaconda虚拟环境进行允许。所以可以省去大量折腾搭建环境以及安装包的问题。
Urllib库
该库用于操作URL模块。
但是该库在python2与python3之间存在较大差距,所以应用时候需要额外注意。
在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中使用urlib2.urlopen--对应的, 在Python3.X中会使用urllib.request.
urlopen。
在Python2.X中使用urlib.urlencode-对 应的,在Python3.X中会使用urllib.parse.
urlencode。
在Python2.X中使用urlib.quote对 应的,在Python3.X 中会使用urlib.request.
quote。
在Python2.X中使用cookielib.CookieJar-对 应的,在Python3.X中会使用http.
CookieJar。
在Python2.X中使用urllib2.Request--对应的, 在Python3.X中会使用urllib.request
Request。
这些只需要知道其意思就行,不需要去记忆。
快速使用Urllib库
import urllib.request
if __name__ == '__main__':
file = urllib.request.urlopen("http://www.baidu.com")
date = file.read()
dataline = file.readline()
print(dataline)
print(date)
这里重点就是一句话:
file = urllib.request.urlopen(“http://www.baidu.com”)
其中括号内的就是需要爬取的URl,这是最简单的使用方法
可以简单的理解,整个网络相当于一个巨型计算机,打开一个URL就像打开巨型计算中一个文件。
将打开的URL信息标记进file中,并且进行想关的读取操作。
光光读取信息是没用的,我们还需要对信息进行保存和处理。
上面已经像文件操作一样,将网页内容读取赋给了变量data,接下来可以将其保存下来:
import urllib.request
if __name__ == '__main__':
file = urllib.request.urlopen("http://www.baidu.com")
data = file.read()
file_store = open("D:\\programfile\\python3\\inf\\crawler.html", "wb")
file_store2 = open("D:\\programfile\\python3\\inf\\crawler.txt", "wb")
file_store.write(data)
file_store2.write(data)
给大家展示一下其相同抓取内容后保存的效果:
上面为保存html,下面为txt。
表现形式不一样的,内容是一样的,可以相互转化。
上面是最简单的用法,下面还有一些重要的方法,可以使得爬取更加便捷和专业:
file=urllib. request. urlretrieve( “http://baidu.com”, filename=“D:\programfile\python3\inf\crawler.html”)
//直接将信息读取入本地文件,不需要上面的各种操作
//但是该操作会产生缓存信息,使得实际产生的文件不止crawler.html一个
//所以可以使用下面的函数进行清楚缓存
urllib.request.urlcleanup()
file.info() //返回与当前环境有关的信息
file.getcode() //获取当前爬取网页的状态码.返回200则为正确。 404 😃
file.geturl() //获取当前爬取的URL地址
eg:
>>>file.geturl()
‘http://www.baidu.com’
网页会对内容进行url编码来表达汉字等一些字符。所以urllib中也有相应的库。
>>>urll ib. request . quote ( “http:// www. sina. com. cn”) //对url进行编码
'http83A// www. sina. com. cn>>>url1 ib. request . unquote ( “http83A// www. sina. com. cn”) //对wrl进行解码
'http:// www. sina. com.cn ’
以上就是urllib的一些基本操作,内容很简单,一举实例便能理解,有这些已经可以实现简单的网页信息爬取了。
爬取反爬页面
很多页面都存在反爬协议,详情可以查看robort.txt,我们在这只是交流分享知识,平时还是需要遵守这些协议。
发生403错误
要绕过爬虫限制首先我们需要了解浏览器的Headers属性:
HTTP Headers是HTTP请求和相应的核心,它承载了关于客户端浏览器,请求页面,服务器等相关的信息。
通过设置headers信息,可以将爬虫模拟成浏览器去访问网站,从而逃跑反爬限制。
设置只需要设置一些User-Agent信息即可,而这个信息可以手动去页面使用开发者工具获得:
F12进入开发者工具
对页面随便进行一个动作:随便点击什么就行。
右上角进入Network查看
所以获得了一个内容:
User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537 .36 ( KHTML,like Gecko) Chrome/75.0.3770.142 Mobile Safari/537 .36
法一:使用build_opener()修改报头
import urllib.request
if __name__ == '__main__':
URL = "https://www.jianshu.com"
headers = ("User-Agent", "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537 .36 ( KHTML,like Gecko) Chrome/75.0.3770.142 Mobile Safari/537 .36")
opener = urllib.request.build_opener()
opener.addheaders = [headers]
data = opener.open(URL).read()
file_store = open("D:\\programfile\\python3\\inf\\crawler.html", "wb")
file_store.write(data)
使用urllib.request.build_opener()创建一个对象opener并且赋给opener,然后设置实例opener的addheaders(头信息,格式: “opener对象名.addheaders=[头信息]”),然后通过opener对象的open()方法来打开对应的网址,成功爬取内容。
法二:使用add_header()添加报头
import urllib.request
if __name__ == '__main__':
URL = "https://www.jianshu.com"
req = urllib.request.Request(URL)
req.add_header('User-Agent', 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537 .36 ( KHTML,like Gecko) Chrome/75.0.3770.142 Mobile Safari/537 .36')
data = urllib.request.urlopen(req).read()
file_store = open("D:\\programfile\\python3\\inf\\crawler.html", "wb")
file_store.write(data)
这个添加报头的方法是设置一个request对象,然后继续按照没用反爬可以爬的方法urlopen()进行打开网址,然后read读入。
超时设置
有时候爬取一个网页会出现长时间未响应的情况。或者有些网站因为科学上网的原因无法响应,所以我们要对爬取过程设置一个超时设置来保证爬取的效率。
import urllib.request
if __name__ == '__main__':
URL = "https://www.baidu.com"
for i in range(10):
try:
file = urllib.request.urlopen(URL,timeout=0.64)
data = file.read()
print(len(data))
except Exception as e:
print("some mistakes ->"+str(e))
这里增加了timeout这个参数来显示反应的时间,如果超过这个时间就会抛出异常
我特意选了一个对应我这网速的响应时间,为了直观的展示其限制超时的效果。
对于有一些网站,本身的架构或者假如的图片,文字特效很多所以响应速度会很慢,所以这些网站进行超时设置的时候可以适当的放大一些时间限制。
HTTP协议请求
GET请求
如果需要在浏览器上查询一个关键词,就需要输入关键词进行检索。
如果需要爬虫自动化的完成这个步骤,就需要学会get请求
在网页上进行检索的时候,输入的检索条件是通过URL来传递的,比如我搜索一些爬虫:
https://cn.bing.com/search?q=%E7%88%AC%E8%99%AB&PC=U316&FORM=CHROMN
那么浏览器上方就会自动解析成URL。
%E7%88%AC%E8%99%AB
这段其实是爬虫的URL编码,而q=“爬虫”,即字段q是存储我们检索关键词的变量,后面一大堆是相当于一个电脑查询的身份证。
我们只需要前面的检索条件就可以完成检索,不信可以试试。
https://cn.bing.com/search?q=%E7%88%AC%E8%99%AB
根据这个结论,就可以通过构造这种get请求,来自动查询某个关键词
而其构造的方法就是把原来爬取的URL修改成后面附加了URL编码搜索信息的内容。
而其构造方法可以脚本化处理成:
URL = "http://www.baidu.com/s?wd="
key = “爬虫”
key_code = urllib.request.quote(key)
#quote只能对于字符串使用,华友一个urlencode可以把字典类型数据中文转化成utf-8处理
url_all = URL+key_code #取代原本的URL,增加了自动搜索关键词的功能
所以通过上面的示例,我们大概可以了解到GET请求的方式:
“http//网址?字段名1=字段内容1&字段名2=字段内容2…"
所以我们使用的思路为:
- 以对应的URL为参数,构建Request对象
- 通过urlopen()打开构造Request对象
- 按照需求额外指定处理操作,读取网页内容,写入文件等…
POST请求
网站进行登录,注册操作的时候都会遇到POST请求,登录时候需要用上Cookie。
Cookie,有时也用其复数形式 Cookies。类型为“小型文本文件”,是某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息
这方面是实操大家可以在这个网站上实践:
http://www.iqianyue.com/mypost/
import urllib.request
if __name__ == '__main__':
url = "http://www.iqianyue.com/mypost/"
postdata = urllib.parse.urlencode({
"name": "test",
"pass": "test"
}).encode('utf-8') # 将数据使用urlencode编码处理后,使用encode()设置为utf-8编码
req = urllib.request.Request(url, postdata)
req.add_header('User-Agent', 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537 .36 ( KHTML,like Gecko) Chrome/75.0.3770.142 Mobile Safari/537 .36')
data = urllib.request.urlopen(req).read()
fhandle = open("D:\\programfile\\python3\\inf\\crawler.html", "wb")
fhandle.write(data)
fhandle.close()
上面这个例子是上面所有内容的一个综合,建议可以自我测试一下,自行编写,考察学习效果。
代理服务器的设置
def use_ proxy (proxy_ addr,url) :
import urllib. request
proxy= urllib.request . ProxyHandler ({ ‘http’ :proxy_ addr})
opener = urllib. request。build_ opener (proxy, urllib. request . HTTPHandler)
urllib. request . install_ opener (opener )data = urllib. request。urlopen (ur1) . read() .decode(‘utf-8’)
return data
proxy_ addr="* *: * * "
data=use proxy (proxy_ addr , “http:// www. baidu. com” )
print (len (data) )
原理和反爬一样,仔细阅读不多赘述。
可以设置多个代理IP,这样长时间对于一个网站的爬取才不会被网站ban了我们的ip。
Debuglog
如果希望爬虫程序边运行边打印调试日志,就需要开启Debuglog
如何开启DebugLog呢?思路如下:
1)分别使用urlib.request.HTTPHandler()和urlib.request.HTTPSHandler()将debuglevel
设置为1。
2)使用urlib.request.build_ opener(创建自定义的ope
pener对象,并使用1)中设置的值
作为参数。
3)用urllib.request.install opener(创 建全局默认的opener对象,这样,在使用
urlopen(时,也会使用我们安装的opener对象。
4)进行后续相应的操作,比如urlopen0等。
此时,根据以上思路,我们可以通过如下代码开启DebugLog:
import urllib.request
if __name__ == '__main__':
httphd = urllib.request.HTTPHandler(debuglevel=1)
httpshd = urllib.request.HTTPSHandler(debuglevel=1)
opener = urllib.request.build_opener(httphd, httpshd)
urllib.request.install_opener(opener)
data = urllib.request.urlopen("http://www.baidu.com").read()
fhandle = open("D:\\programfile\\python3\\inf\\crawler.html", "wb")
fhandle.write(data)
fhandle.close()
运行程序以后在输出当中会同时出现很多报头信息,即成功开启DebugLog。
URLError
在程序爬取的过程中难免会出现报错异常的情况,所以必须要能合理处理异常。
常用的两个强大的类:URLError以及HTTPError
URLError
产生URLError的原因:
- 网络无连接
- 连接不到特定服务器
- 服务器不存在
- URLError触发
HTTPError
HTTPError是URLError的字类,
常见的状态码:重点关注黑体字:
100:继续 客户端应当继续发送请求。客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应。
101: 转换协议 在发送完这个响应最后的空行后,服务器将会切换到在Upgrade 消息头中定义的那些协议。只有在切换新的协议更有好处的时候才应该采取类似措施。
102:继续处理 由WebDAV(RFC 2518)扩展的状态码,代表处理将被继续执行。
200:请求成功 处理方式:获得响应的内容,进行处理
201:请求完成,结果是创建了新资源。新创建资源的URI可在响应的实体中得到 处理方式:爬虫中不会遇到
202:请求被接受,但处理尚未完成 处理方式:阻塞等待
204:服务器端已经实现了请求,但是没有返回新的信 息。如果客户是用户代理,则无须为此更新自身的文档视图。 处理方式:丢弃
300:该状态码不被HTTP/1.0的应用程序直接使用, 只是作为3XX类型回应的默认解释。存在多个可用的被请求资源。 处理方式:若程序中能够处理,则进行进一步处理,如果程序中不能处理,则丢弃
301:请求到的资源都会分配一个永久的URL,这样就可以在将来通过该URL来访问此资源 处理方式:重定向到分配的URL302:请求到的资源在一个不同的URL处临时保存 处理方式:重定向到临时的URL
304:请求的资源未更新 处理方式:丢弃
400:非法请求 处理方式:丢弃
401:未授权 处理方式:丢弃
403:禁止 处理方式:丢弃
404:没有找到 处理方式:丢弃
500:服务器内部错误 服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器端的源代码出现错误时出现。
501:服务器无法识别 服务器不支持当前请求所需要的某个功能。当服务器无法识别请求的方法,并且无法支持其对任何资源的请求。
502:错误网关 作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。
503:服务出错 由于临时的服务器维护或者过载,服务器当前无法处理请求。这个状况是临时的,并且将在一段时间以后恢复。
import urllib.request
if __name__ == '__main__':
try:
urllib.request.urlopen("https://www.jianshu.com/")
except urllib.error.URLError as e:
print(e)
输出:
D:\Anaconda3\python.exe D:/programfile/python3/Crawler/pass_crawler.py
HTTP Error 403: ForbiddenProcess finished with exit code 0
本篇小结:爬虫就像一个小小的寄生虫,在网页上高效汲取我们所需要的养料。通过本篇内容的讲解,已经可以实现静态定向爬虫的各种场景实战,对于一些反爬网页也可以爬取所需要的信息,并且能够使用代理IP进行爬取。并且可以选择关键词对网页内容进行爬取。对于一些仅仅需要爬取部分文章或者检索网页关键词信息来关注风向的同志,现在就可以开始针对自己想爬取的内容进行实战了。