『第一周』网络爬虫之规则

2020-03-31 Views Python | 爬虫 | 科技4334字23 min read
featureimg

中国大学MOOC课程笔记

【第一周】网络爬虫之规则

【第一周】网络爬虫之规则

单元1:Requests库入门

安装

win+R cmd
pip install requsets

测试安装成功

import requests

get()方法

r = requests.get(url)#获得网页
#返回一个包含服务器资源的response对象
#构造一个向服务器请求资源的request对象

完整使用方法:

request.get(url,params=None,**kwargs)
#url:拟获取页面的url链接
#params:Url中的额外参数,字典或字节流格式,可选
#**kwargs:12个控制访问的参数

Response对象的属性

属性说明具体说明
r.status_codeHttp请求的返回状态,200表示连接成功,404表示失败只有返回200,response其他属性才可用;404或其他某些原因出错将产生异常
r.textHttp响应内容的字符串形式,即,url对应的页面内容
r.encoding从HTTP header中猜测的响应内容编码方式如果header中不存在charset,则认为编码为ISO-8859-1
r.apparent_encoding从内容中分析出的相应内容编码方式(备选编码方式)根据网页内容分析出的编码方式,更准确
r.contentHttp响应内容的二进制形式

爬取网页的通用代码框架

理解requests库的异常

异常说明
requests.ConnectionError网络连接错误异常,如DNS查询失败,拒绝连接等
requests.HTTPErrorHttp错误异常
requests.URLRequiredUrl缺失异常
requests.TooManyRedirects超过最大重定向次数,产生重定向异常
requests.ConnectTimeout连接远程服务器时超时异常
requests.Timeout 请求url超时产生超时异常
r.raise_for_status()如果不是200,产生异常requests.HTTPError
#有效稳定的代码框架
import requests

def getHTMLText(url):
try:
r = requests.get(url, timeout = 30)
r.raise_for_status()#如果状态不是200,引发HTTPError异常
r.encoding = r.apparent_encoding
return r.text
except:
return "error"

if name == "main":
url = "http://www.baidu.com"
print(getHTMLText(url))

HTTP协议及Requests库方法

Requests库的7个主要方法

方法说明
requests.request()构造一个请求,支撑以下各方法的基础方法
requests.get()获取HTML网页的主要方法,对应于HTTP的GET
requests.head()获取HTML网页头信息的方法,对应于HTTP的HEAD
requests.post()向HTML网页提交POST请求的方法,对应于HTTP的POST
requests.put()向HTML网页提交PUT请求的方法,对应于HTTP的PUT
requests.patch()向HTML网页提交局部修改请求,对应于HTTP的PATCH
requests.delete()向HTML页面提交删除请求,对应于HTTP的DELETE

Http协议与request库

HTTP协议方法Requests库方法功能一致性
GETrequests.get()一致
HEADrequests.head()一致
POSTrequests.post()一致
PUTrequests.put()一致
PATCHrequests.patch()一致
DELETErequests.delete()一致

head()方法

>>>r=requests.head('http://httpbin.org/get')
>>>r.headers
{'Content-Length':'238','Access-Control-Allow-Origin':'*',
'Access-control-Allow-Credentials':'true',
'Content-Type':'application/json',
'Server':‘nginx','Connection':‘keep-alive',
'Date':'Sat,18 Feb 2017 12:07:44GMT'}
>>>r.text
..

post()方法

#向URL POST一个字典自动编码为form(表单)
>>>payload={'key1':'value1','key2':'value2'}
>>>r=requests.post("http://httpbin.org/post',data=payload)
>>>print(r.text)
{..
    "form":{
		    "key2":"value2",
				"key1":"value1"
		},
}

#向URL POST一个字符串自动编码为data
>>>r=requests.post('http://httpbin.org/post',data='ABC')
>>>print(r.text)
{...
"data":"ABC"
"form":{},
}

put()方法

>>>payload={'key1':'value1','key2':'value2'} }
>>>r=requests.put('http://httpbin.org/put',data= payload)
>>>print(r.text)
{...
"form":{
"key2":"value2",
"key1":"value1"
},
}

Requests库主要方法解析

Requests库的7个主要方法

方法说明
requests.request()构造一个请求,支撑以下各方法的基础方法
requests.get()获取HTML网页的主要方法,对应于HTTP的GET
requests.head()获取HTML网页头信息的方法,对应于HTTP的HEAD
requests.post()向HTML网页提交POST请求的方法,对应于HTTP的POST
requests.put()向HTML网页提交PUT请求的方法,对应于HTTP的PUT
requests.patch()向HTML网页提交局部修改请求,对应于HTTP的PATCH
requests.delete()向HTML页面提交删除请求,对应于HTTP的DELETE
1.
requests.request(method,url,**kwargs)

#method:请求方式,对应get/put/post等7种
#url:拟获取页面的url链接
#**kwargs:控制访问的参数,共13个
#params:字典或字节序列,作为参数增加到url中
#data:字典、字节序列或文件对象,作为request的内容
#json:JSON格式的数据,作为Request的内容
#headers:字典,HTTP定制头
#cookies:字典或CookieJar,Request中的cookie
#auth:元组,支持HTTP认证功能
#files:字典类型,传输文件
#timeout:设定超时时间,单位为s
#防止对爬虫对逆追踪
#proxies:字典类型,设定访问代理服务器,可以增加登录认证
#高级功能
#allow_redirects:True/False,默认True,重定向开关
#stream:True/False,默认True,获取内容立即下载开关
#verify:True/False,默认True,认证SSL证书开关
#cert:本地SSL证书路径

2.
requests.get(url,params=None,**kwargs)

#url:拟获取页面的url链接
#params:url中的额外参数,字典或字节流格式,可选
#**kwargs:12个控制访问的参数

3.
requests.head(url,**kwargs)

#url:拟获取页面的url链接
#**kwargs:13个控制访问的参数

4.
requests.post(url,data=None,json=None,**kwargs)

#url:拟获取页面的url链接
#data:字典、字节序列或文件,Request的内容
#json:JSON格式的数据,Request的内容
#**kwargs:11个控制访问的参数

5.
requests.put(url,data=None,**kwargs)

#url:拟获取页面的url链接
#data:字典、字节序列或文件,Request的内容
#**kwargs:12个控制访问的参数

6.
requests.patch(url,data=None,**kwargs)

#url:拟获取页面的url链接
#data:字典、字节序列或文件,Request的内容
#**kwargs:12个控制访问的参数

7.
requests.delete(url,**kwargs)

#url:拟获取页面的url链接
#**kwargs:13个控制访问的参数

PS:不常用字段放在可选字段中

单元小结

网络连接有风险,异常处理很重要

单元2:网络爬虫的“盗亦有道”

网络爬虫引发的问题

网络爬虫的限制

  • 来源审查:判断User-Agent进行限制
    • 检查来访HTTP协议头的User-Agent域,只响应浏览器或友好爬虫的访问。
  • 发布公告:Robots协议
    • 告知所有爬虫网站的爬取策略,要求爬虫遵守。

Robots协议

以京东(www.jd.com)为例访问其robots协议:www.jd.com/robots.txt

<img style="width:776px" src="F:\7IT\GrideaDocument\images\第一周配图.png

"/>

Robots协议基本语法

“#” 表示注释,“*”代表所有,“/”代表根目录

Robots协议的遵守方式

Robots协议的使用

  • 网络爬虫:自动或人工识别robots.txt,再进行内容爬取。
  • 约束性:Robots协议是建议但非约束性,网络爬虫可以不遵守,但存在法律风险。

对Robots协议的理解

123
访问量很小:可以遵守非商业且偶尔:建议遵守必须遵守
访问量较大:建议遵守 商业利益:必须遵守必须遵守
爬取网页 玩转网页爬取网站 爬取系列网站爬取全网

单元3:Requests库网络爬虫实战(5个实例)

实例1:京东商品页面的爬取

import requests
url = "https://item.jd.com/6449103.html"
try:
r = requests.get(url, timeout = 30)
r.raise_for_status()#如果状态不是200,引发HTTPError异常
r.encoding = r.apparent_encoding print(r.text[:1000])
except:
print("error")

实例2:亚马逊商品页面的爬取

#初写代码
import requests
url = "https://www.amazon.cn/dp/B07CM2DX6J/ref=sr_1_2?ie=UTF8&qid=1549169407&sr=8-2&keywords=%E7%B4%A2%E5%B0%BC6300%E5%BE%AE%E5%8D%95"
r = requests.get(url)
r.raise_for_status
'''
out:
<bound method Response.raise_for_status of <Response [503]>>
'''
#在加上两行代码
r.encoding = r.apparent_encoding
r.request.headers
'''
out:
{'User-Agent': 'python-requests/2.14.2', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
!!!!!'User-Agent': 'python-requests/2.14.2'!!!!!
'''
#完整代码
import requests
url = "https://www.amazon.cn/dp/B07CM2DX6J/ref=sr_1_2?ie=UTF8&qid=1549169407&sr=8-2&keywords=%E7%B4%A2%E5%B0%BC6300%E5%BE%AE%E5%8D%95"
try: 
		kv = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'} 
		r = requests.get(url,headers = kv) 
		r.raise_for_status()#如果状态不是200,引发HTTPError异常 
		r.encoding = r.apparent_encoding print(r.text[:2000])
except: 
		print("error")

实例3:百度/360搜索关键词提交

搜索引擎关键词提交接口

百度的关键词接口:http://www.baidu.com/s?wd=keyword

360的关键词接口:http://www.so.com/s?q=keyword

#初写代码
import requests
kv = {'wd':'python'}#构造键值对
url = "http://www.baidu.com/s"
r = requests.get(url,params = kv)
r.status_code
#Out[1]:200
r.request.url
#Out[2]:'http:www.baidu.com/s?wd=python'
len(r.text)
#Out[3]:430022 #430K左右
#完整代码
import requests
keyword = "Python"
try: 
		kv = {'wd':keyword} 
		url = "http://www.baidu.com/s" 
		r = requests.get(url,params = kv) 
		print(r.request.url) 
		r.raise_for_status() 
		print(len(r.text))
except: 
		print("error")

实例4:网络图片对爬取和存储

#初写代码
import requests
path = "F:/7IT/JupyterNotebook/requests小实例/photo/abc.jpg"
url = "http://image.nationalgeographic.com.cn/2017/0211/20170211061910157.jpg"
r = requests.get(url)
r.raise_for_status
#二进制存储
with open(path, 'wb') as f: 
		f.write(r.content) 
		f.close()

#完整代码
import requests
import os
url = "http://image.nationalgeographic.com.cn/2017/0211/20170211061910157.jpg"
root = "F://7IT//JupyterNotebook//requests小实例//photo//"
path = root + url.split('/')[-1]
try: 
		if not os.path.exists(root):#检查路径是否存在 
				os.mkdir(root)#创建目录 
		if not os.path.exists(path): 
				r = requests.get(url) 
				with open(path, 'wb') as f: 
						f.write(r.content) 
						f.close() 
						print("sucessfully save!") 
		else: print("file exits")
except: 
		print("error")

实例5:IP地址归属地的自动查询

#初写代码
import requests
url = "http://www.ip138.com/ips138.asp?ip="
r = requests.get(url + '202.204.80.112')
r.status_code
r.encoding = r.apparent_encoding
r.text[-500:]#检测数据时若无限制,会导致无效,尽量对text有所限制

#完整代码
import requests
url = "http://www.ip138.com/ips138.asp?ip="
try: r = requests.get(url + '202.204.80.112') r.raise_for_status() r.encoding = r.apparent_encoding print(r.text[-500:])
except: print("errror")
EOF