最近在学习Python爬虫内容,其实很多知识在网上搜索一下都能查到,但是作为自己的一种学习记录,也是回顾与复习呀。
这种东西真的变化超级快,以前可以直接爬取的内容,现在很多网站都增加了反爬机制,报错家常便饭TAT,常常觉得自己是bug生产机,不过毕竟前人栽树后人乘凉,大多数问题都可以通过检索得到解决,能成功解决问题也是成就感的来源之一呢~
总结来说爬虫是从网络获取信息、解析信息并最终输出为需要格式的过程。
说起来也挺有意思的,用公众号顺带掌握了一波公共号排版和插入代码的小技巧哈哈。好啦,那我们一起开始叭!
以下内容主要来源于中国大学MOOC--Python网络爬虫与信息提取--北京理工大学。仅供个人学习使用。(代码部分可右滑阅读全部内容)
需要有Python基础知识才能看懂哦~不然就跟第一次接触的我一样,全程听天书QAQ
思维导图
第一周 网络爬虫规则
1.1Request库入门
Request库的安装
需要安装request库,判断安装情况:code返回200说明成功
import requests
r = requests.get("https://www.baidu.com")
print(r.status_code)
r.encoding = 'utf-8'
print(r.text)
request库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的PDELETE |
Request库的get()方法
r = request.get(url) 通过get(url)构造一个向服务器请求资源的Request对象 request.get是返回一个包含服务器资源的Response对象
完整形式
r = request.get(url,params=None,**kwargs)
url:拟获取页面的url链接
(个人理解url是网页访问地址https://developer.mozilla.org/zh-CN/docs/Learn/Common_questions/What_is_a_URL)
params:url中的额外参数,字典或字节流格式,可选
**kwargs:12个控制访问的参数
response对象的属性属性 | 说明 |
r.status_code | HTTP请求的返回状态,200表示连接成功,404失败 |
r.text | HTTP相应内容的字符串形式,即url对应的页面内容 |
r.encoding | 从HTTP header中猜测的响应内容编码方式 |
r.apparent_encoding | 从内容中分析的响应内容编码方式(备选编码方式) |
r.content | HTTP响应内容的二进制方式 |
r.status_code(200)→r.encoding/r.apparent_encoding/r.content
r.encoding: 若header中不存在charset,则认为编码为ISO-8859-1
个人理解,encoding是从head中charset部分提取得到的编码方式,而apparent_encoding是根据整体内容分析得到的编码方式,因此更为准确,但同时速度可能慢一些
爬取网页的通用代码框架
request库异常异常 | 说明 |
requests.ConnectionError | 网络连接错误异常,如DNS查询失败、拒绝连接等(仅限连接时的异常) |
requests.HTTPError | HTTP错误异常 |
requests.URLRequired | URL缺失异常 |
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()
r.encoding = r.apparent_encoding
return r.text
except:
return "产生异常"
url = "https://www.baidu.com"
print(getHTMLTEXT(url))
使得爬取网页更加稳定、有效、可靠
HTTP协议及Request库方法
HTTP,Hypertext Transfer Protocol,超文本传输协议。
HTTP是一个基于“请求与响应”模式的、无状态的应用层协议。用户发起请求,服务器做出响应。无状态指不同次数之间的访问没有相互关联。HTTP协议采用URL作为定位网络资源的标识。
URL格式:http://host[:port][path]
host:合法的Internet主机域名或IP地址
port:端口号,默认端口为80
path:内部路径
url是通过HTTP协议存取资源的一个路径(类似电脑中对应的文件夹路径,但此路径再Internet上),每一个url对应一个数据资源
(URL定义参考 https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_is_a_URL)
方法 | 说明 |
GET | 请求获取URL位置的资源 |
HEAD | 请求获取URL位置资源的头部信息 |
POST | 请求向URL位置的资源后附加新的数据 |
PUT | 请求向URL位置存储一个资源,覆盖原URL位置的资源 |
PATCH | 请求局部更新URL位置的资源,即改变该处资源的部分内容 |
DELETE | 请求删除URL位置存储的资源 |
云端上的所有资源通过URL进行标识,通过GET\HEAD获得资源,通过PUT\POST\PATCH\DELETE对云端资源进行修改(每一次操作独立无状态的)
PATCH\PUT区别:用PATCH只需要改变一个地方的内容,PUT要将改变的内容及其他未改变内容一并提交。PATCH优点是节省网络带宽。HTTP协议与request库方法是一致的。
POST方法 提交列表,会默认进入form中;提交字符串,默认编码为data PUT类似
request库主要方法解析
向URL POST一个字典,自动编码为表单(form),POST一个字符串,自动编码为data
requests.request(method,url,**kwargs)
method:请求方式,对应get等7种
url:拟获取页面的URL链接
**kwargs:控制访问的参数,共13个
可选参数:params:字典或字节序列,作为参数增加到url中 相当于筛选资源
data:字典、字节序列或文件对象,作为request的内容 理解是把内容存储到对应的url中
json:JSON格式的数据,作为内容部分可以向服务器提交
headers:字典,HTTP定制头 访问时的头字段 可以模拟浏览器向服务器中发起访问
cookies:字典或CookieJar,request中的cookie
auth:元组,支持HTTP认证功能
files:字典类型,传输文件 向链接提交文件
timeout:设定超时时间,以秒为单位
proxies:字典类型,设定访问相关的代理服务器,可以增加登录认证 例如访问百度时可以采用代理服务器的地址,隐藏源地址(感觉有点像VPN的道理)
allow_redirects:True/False,默认为T,重定向开关 是否允许重定向
stream:True/False,默认为T,获取内容立即下载开关
verify:True/False,默认为T,认证SSL证书开关
cert:保存本地SSL证书路径的字段(不详细介绍)
小结:对网络爬取,主要关注get和head即可。
课后练习1:成功爬取网页100次并测试时间
import requests as rq
import time
def gethtml(url):
try:
r = rq.get(url)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r
except:
return '爬取失败'
if __name__ == '__main__': # 如果模块是被直接运行的,则代码块被运行,如果模块是被导入的,则代码块不被运行。
start = time.perf_counter()
url = 'http://baidu.com'
for i in range(100):
gethtml(url)
end = time.perf_counter()
print('一百次爬取时间为{:.2f}秒'.format(end-start)) #保留两位小数
time.perf_counter() # 调用一次 perf_counter(),从计算机系统里随机选一个时间点A,
计算其距离当前时间点B1有多少秒。当第二次调用该函数时,默认从第一次调用的时间点A算起,
课后练习2:获得GitHub的小图标
import requests as rq
r= rq.get("https://github.com/favicon.ico")
with open('favicon.ico','wb') as f: #favicon.ico,文件名称 wb 读写方式
f.write(r.content)
wb以二进制格式打开一个文件只用于写入。open函数介绍https://www.runoob.com/python/python-func-open.html用Session可以模拟同一个对话而维持cookies,常用于模拟登陆成功后的下一步操作。对显示证书错误的页面,可以通过设置verify参数为false,并用disable_warnings等方法屏蔽证书错误警告。可用proxies参数设置代理。
参考资料
作业代码参考https://developer.aliyun.com/article/637534
对time.perf_counter()理解https://www.runoob.com/note/35499
对if __name__ == '__main__'理解https://blog.konghy.cn/2017/04/24/python-entry-program/?spm=a2c6h.12873639.0.0.7928184dD8jlCj
对format函数的理解https://www.runoob.com/python/att-string-format.html
排版 135编辑器
代码在线编辑网站:http://md.aclickall.com/