python-爬虫的分类urllib、requests
网络爬虫按照系统结构和实现技术,大致分为以下几种类型:
1、通用网络爬虫、聚焦网络爬虫、增量式网络爬虫、深层网络爬虫,实际的网络爬虫系统通常是几种爬虫技术相结合实现的。
a.通用网络爬虫:类似于搜索引擎一样,通过关键字的检索搜索相关的网络数据。
b.聚焦网络爬虫:一个自动下载网页的程序,根据抓取目标,有选择的访问万维网上的网页链接,获取所需要的信息。只会针对性的获取某些网络数据
c.增量式网络爬虫:是对已下载的网页进行增量式的更新和只爬取新增加的或者已经发生变化的网页的爬虫,在一定程度上保证所爬取的网页是新的页面,和周期性爬行和刷新页面的网络爬虫比较,增量式爬虫只会在需要的时候爬行新产生的网页和更新,减少时间和空间上的消耗,但是增加了爬行算法的复杂度和实现难度。
d.深层网络爬虫:Web页面按存在方式可以分为表层网页和深层网页表层网页:搜索引擎可以搜索到的页面。深层网页:不能通过静态链接获取的,隐藏在搜索表单后,只有一些用户提交一些关键词才能获得的web页面。(爬取贴吧或者论坛中的数据,只有登录才能获取的信息)
2、网络爬虫的工作流程:
a.选取一部分精心挑选的种子URL。
b.将这些URL放入带抓取URL队列。
c.从待抓取网页的URL队列中获取URL,解析DNS,并且的二道主机IP,并将URL对应的网页下载下来,进行存储,并且把这些URL放入到已抓取的URL队列中。
d.分析已抓取URL队列中的URL,从已下载的网页中提取其他URL,并和已抓取的URL进行比较去重,最后将去重过的URL放入待抓取URL队列中,进入下一循环。
3、Python中三种实现HTTP请求的方式:
a.urlib2(2.x)/urllib.request(3.x)
b.httplib/urllib是一个底层的基础模块,功能比较少,用的也不多(略过)
c.Requests-> 灰常人性化的requests是我们爬虫中最常用的库,功能很强大,用着也舒坦。
urllib.request:
#!/usr/bin/env python # -*- coding: utf-8 -*- __author__ = 'Fade Zhao' import urllib.request import urllib import urllib.parse from http import cookiejar # GET url = 'https://wwww.baidu.com' response = urllib.request.urlopen(url) html = response.read() print(html) # POST 提交数据 url = 'http://127.0.0.1:8000/spider' postData = { 'username':'username', 'passwor':'xxxxxx' } headers = { 'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1)', 'referer':'http://www.xxxx.com' } data = urllib.parse.urlencode(postData).encode(encoding='utf-8') # 添加headers,url,data req = urllib.request.Request(url=url,data=data,headers=headers) response = urllib.request.urlopen(req) html = response.read() print(html.decode()) # 获取cookie # 1、创建cookie url = 'http://127.0.0.1:8000/spider' cookie = cookiejar.CookieJar() # 设置opener opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cookie)) response = opener.open(url) for item in cookie: print(item.name,':',item.value) html = response.read().decode() print(html) # 添加cookie url = 'http://127.0.0.1:8000/spider' opener = urllib.request.build_opener() opener.addheaders.append(('cookie','email=6666')) req = urllib.request.Request(url) response = opener.open(url) html = response.read().decode() print(html) # 获取HTTP响应码,200 OK的响应码用urlopen的方法获取的response只需要用到getcode(),但是其他的响应码就会出现错误,是需要进行错误抓取进行分析 url = 'http://127.0.0.1:8000/spider' try: response = urllib.request.urlopen(url) print(response.getcode()) except Exception as e: print('Error:',e) else: print(response.read().decode()) # 在使用爬虫爬取网络数据的时候经常会用到代理,需要ProxyHandler来进行设置代理 url = 'https://www.baidu.com' proxy = urllib.request.ProxyHandler({'http':'127.0.0.1:8888'}) opener = urllib.request.build_opener(proxy) # 设置全局的proxy urllib.request.install_opener(opener) response = urllib.request.urlopen(url) print(response.read().decode()) # 需要注意的是urllib.install_opener 是创建全局的代理,这之后的所有urllib爬虫都走这个代理,虽然很方便,但是不能够更下细致和灵活。所以我们可以直接用opener.open直接访问 url = 'https://www.baidu.com' proxy = urllib.request.ProxyHandler({'http':'127.0.0.1:8888'}) opener = urllib.request.build_opener(proxy) response = opener.open(url) print(response.read().decode())
requests:
#!/usr/bin/env python # -*- coding: utf-8 -*- __author__ = 'Fade Zhao' import requests '''1、requests请求''' url = 'http://127.0.0.1:8000/spider' response = requests.get(url) response.encoding='utf-8' print(response.text) # 同时也支持多种http请求 # response = requests.post(url) # response = requests.delete(url) # response = requests.options(url) # response = requests.head(url) # get通过url提交数据 url = 'https://www.baidu.com/s' data = { 'wd':'麦克雷' } response = requests.get(url,params=data) print(response.url) # https://www.baidu.com/s?wd=%E9%BA%A6%E5%85%8B%E9%9B%B7 '''2、响应与编码''' url = 'http://127.0.0.1:8000/spider' response = requests.get(url) print(response.content) # 返回 字节形式 print(response.text) # 返回文本形式 print(response.encoding) #返回的是HTTP猜测的网页编码格式 #设置为utf-8 输出text后出现乱码可以使用↓↓↓的方法进行转码,但是这种方式太笨了,可以通过chardet来进行编码检测 response.encoding = 'utf-8' # 使用chardet.detect方法可直接返回content的编码格式 import chardet response.encoding = chardet.detect(response.content).get('encoding') print(response.text) '''3、请求头headers处理''' # requests与urllib添加请求头的方式大致一样,在get请求中添加headers参数就行 headers = { 'User-Agent':'Mozilla/5.0 (Macintosh; Intel …) Gecko/20100101 Firefox/57.0' } # response = requests.get(url,headers=headers) '''4、响应编码与响应头header处理''' url = 'http://127.0.0.1:8000/spider' response = requests.get(url) if response.status_code == requests.codes.ok: res_header = response.headers #响应头 print('响应头~',res_header) print(res_header.get('content-type')) else: # 主动产生异常,如有4XX或5XXX时,会抛出异常 try: response.raise_for_status() except Exception as e: print('响应码异常:',e) '''5、Cookie设置''' url = 'http://127.0.0.1:8000/spider' response = requests.get(url=url) cookie = response.cookies print(cookie) # cookie 的存储类型是属于dict格式,可以通过get(key)的方式来获取value print(cookie.get('name')) # # 添加cookie url = 'http://127.0.0.1:8000/spider' # 这里的cookies是一个字典格式的数据。 # 在Cookie Version 0中规定空格、方括号、圆括号、等于号、逗号、双引号、斜杠、问号、@,冒号,分号等特殊符号都不能作为Cookie的内容。 cookie = {'testCookies_1': 'Hello_Python3', 'testCookies_2': 'Hello_Requests'} response = requests.get(url=url,cookies=cookie) print(response.cookies.get('name')) # >>> LetMe # 在用Post登陆网站的时候,如果提交的cookies没有之前访问网站浏览cookies,网站会拒绝这次的表单提交,所以requests提供了session用来携带cookies进行登录跳转 url = 'http://127.0.0.1:8000/Blog/login.html' session = requests.Session() # 首先获取登陆页面,对于游客,服务器会分配一个cookies response = session.get(url) data ={ 'username':'alex', 'password':'alex', } # 还是用这个带有cookies的session进行登录验证 response_login = session.post(url,data=data) # print(response.text) # 在上边的登陆验证中,无论用户是以什么样的方式访问页面(登陆/浏览),服务器都会分配一个cookies,如果提交表单的时候没有携带cookies进行登录,服务器会将你视为非法用户导致登陆失败。 '''6、重定向''' # 在登陆中,都会有跳转重定向之类的问题,requests做的很好,在get/post请求中默认的allow_redirects=True,当allow_redirects设置为True时是支持网页跳转的 url = 'http://www.github.com' response = requests.get(url) print(response.status_code) # >>>200 # 如果允许重定向,可以通过history来查询历史重定向记录 print(response.history) #[<Response [301]>, <Response [301]>] print(response.url) #打印结果为 https://github.com/ # 为什么会是https,是因为github会把所有http的请求重定向为https请求。 '''7、超时设置''' # 在get/post请求函数中通过timeout设置,单位为秒 response = requests.get(url,timeout=10) '''8、代理设置''' # 同上,也是在get/post请求函数中设置 url = 'http://127.0.0.1:8000/' proxy = { 'https':'60.255.186.169:8888', 'http':'61.135.217.7:80' } response = requests.get(url,proxies=proxy) print(response.text)
通过requests爬取小说实例