一、Requests模块
爬虫的基本框架是获取HTML页面信息,解析页面信息,保存结果,requests模块是用于第一步获取HTML页面信息; requests库用于爬取HTML页面,提交网络请求,基于urllib,但比urllib更方便;
二、模块安装
三、简单使用
- 获取网页内容
# -*- coding: UTF-8 -*-
import requests
r = requests.get("http://www.baidu.com")
# 获取状态码
statusCode=r.status_code
print(statusCode)
# 设定编码
r.encoding = "utf-8"
# 获取内容
print(r.text)
四、 requests模块主要方法
- requests.get方法
获得一个网页的最简单的一行代码就是
r = requests.get(url)
requests.get函数的完整使用方法有三个参数
requests.get(url, params=None, **kwargs)
·url
: 拟获取页面的url链接
·params
: url中的额外参数,字典或字节流格式,可选
·**kwargs
: 12个控制访问的参数
在Response对象中,最常用的是如下五个属性,它们是访问网页最常用也是最必要的属性:
(1) r.status_code
HTTP请求的返回状态,200表示连接成功,404表示失败
(2 )r.text
HTTP响应内容的字符串形式,即,url对应的页面内容
(3) r.encoding
从HTTP header中猜测的响应内容编码方式
(4) r.apparent_encoding
从内容中分析出的响应内容编码方式(备选编码方式)
(5) r.content
HTTP响应内容的二进制形式,比如:我们从一个url链接上获得一个图片,这个图片里的资源是以二进制形式存储的,那我就可以用r.content来还原这个图片。
在使用get方法获得网络资源的时候,有如下的基本流程:
先用r.status_code
来检查状态,如果是200,则可以用r.text
,r.encoding
,r.apparent_encoding,r.content
去解析访问的内容;
如果返回的状态码是404或者是其他,则说明这次访问因某些原因出错,将产生异常。
- Response编码
r.encoding是从HTTP header中猜测的响应内容编码方式
r.apparent_encoding是从内容中分析出的响应内容编码方式(备选编码方式)
r.encoding:如果header中不存在charset,则认为编码为ISO‐8859‐1
r.text根据r.encoding显示网页内容
r.apparent_encoding:根据网页内容分析出的编码方式可以看作是r.encoding的备选
Requests库支持6种常用的连结异常
(1)requests.ConnectionError 网络连接错误异常,如DNS查询失败、拒绝连接等
(2)requests.HTTPError HTTP错误异常
(3)requests.URLRequired URL缺失异常
(4)equests.TooManyRedirects 超过最大重定向次数,产生重定向异常
(5)requests.ConnectTimeout 连接远程服务器超时异常
(6)requests.Timeout 请求URL超时,产生超时请求方式
r = requests.request('GET', url, **kwargs)
r = requests.request('HEAD', url, **kwargs)
r = requests.request('POST', url, **kwargs)
r = requests.request('PUT', url, **kwargs)
r = requests.request('PATCH', url, **kwargs)
r = requests.request('delete', url, **kwargs)
r = requests.request('OPTIONS', url, **kwargs)
它所对应的就是HTTP的请求功能
**kwargs: 控制访问的参数,共13个
1)params : 字典或字节序列,作为参数增加到url中
2)data : 字典、字节序列或文件对象,作为Request的内容
3)json : JSON格式的数据,作为Request的内容
4)headers : 字典,HTTP定制头
5)cookies : 字典或CookieJar,Request中的cookie
6)auth : 元组,支持HTTP认证功能
7)files : 字典类型,传输文件
8)timeout : 设定超时时间,秒为单位
9)proxies : 字典类型,设定访问代理服务器,可以增加登录认证
10)allow_redirects : True/False,默认为True,重定向开关
11)stream : True/False,默认为True,获取内容立即下载开关
12)verify : True/False,默认为True,认证SSL证书开关
13)cert : 本地SSL证书路径requests.head()方法
获取HTML网页头信息的方法,对应于HTTP的HEAD
requests.head(url, kwargs)
·url : 拟获取页面的url链接
·kwargs: 12个控制访问的参数requests.post()方法
向HTML网页提交POST请求的方法,对应于HTTP的POST
requests.post(url, data=None, json=None, kwargs)
·url : 拟更新页面的url链接
·data :字典、字节序列或文件,Request的内容
·json : JSON格式的数据,Request的内容
·kwargs: 12个控制访问的参数
8.requests.put()方法
向HTML网页提交PUT请求的方法,对应于HTTP的PUT
requests.put(url, data=None, kwargs)
·url : 拟更新页面的url链接
·data :字典、字节序列或文件,Request的内容
·kwargs: 12个控制访问的参数
requests.patch()方法
向HTML网页提交局部修改请求,对应于HTTP的PATCH
requests.patch(url, data=None, kwargs)
·url : 拟更新页面的url链接
·data :字典、字节序列或文件,Request的内容
·kwargs: 12个控制访问的参数requests.delete()方法
向HTML页面提交删除请求,对应于HTTP的DELETE
requests.delete(url, kwargs)
·url : 拟删除页面的url链接
·kwargs: 12个控制访问的
五、 通用代码框架
# -*- coding: UTF-8 -*-
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 "产生异常"
if __name__ == "__main__":
url = "http://www.baidu.com"
print(getHTMLText(url))
六、 示例
- 亚马逊商品页面的爬取
# -*- coding: UTF-8 -*-
import requests
url = "https://www.amazon.cn/dp/B07G2MYVWW/ref=zg_bs_books_2?_encoding=UTF8&psc=1&refRID=07KEEHE515Q0CAGQH8K8"
try:
kv = {'user-agent':'Mozilla/5.0'}
r = requests.get(url, headers = kv)
r.raise_for_status()
r.encoding = r.apparent_encoding
# 所有内容
print(r.text)
# 选取指定字符串
print(r.text[1000:2000])
except:
print("爬取失败")
- 百度/360搜索关键词提交
用程序向搜索引擎自动地提交个关键词并获得它的搜索结果
对关键词的搜索提供了一个接口
百度的关键词接口:
http://www.baidu.com/s?wd=keyword
构造一个url链接,包含我们要搜索的关键词
参数params,它可以向url中增加相关的内容
从返回的信息中解析百度返回的链接与返回的内容
# -*- coding: UTF-8 -*-
import requests
"""
百度/360搜索关键词提交
"""
keyword='Python'
try:
#百度关键字
kv={'wd':keyword}
#360关键字
# kv={'q':keyword}
r=requests.get("http://www.baidu.com/s",params=kv)
print(r.request.url)
r.raise_for_status()
print(len(r.text))
except:
print("爬取失败")
- 网络图片的爬取和存储
网络图片链接的格式:http://www.xxxxx.com/picture.jpg
# -*- coding: UTF-8 -*-
import requests
import os
'''
3. 网络图片的爬取和存储
'''
url = "http://image.nationalgeographic.com.cn/2017/0822/20170822095949354.jpg"
root = "D://pics//"
path = root + url.split('/')[-1]
try:
if not os.path.exists(root):
os.mkdir(root)
if os.path.exists(root):
r = requests.get(url)
with open(path,'wb') as f:
f.write(r.content)
f.close()
print("文件保存成功")
else:
print("文件已存在")
except:
print("爬取失败")
- IP地址归属地的自动查询
想要判断一个网址的归属地必须有一个库,程序并没有这样的库,在网上找相关的资源.事实上一个叫ip138的网站提供这样的功能:
http://m.ip138.com/ip.asp?ip=ipaddress
# -*- coding: UTF-8 -*-
import requests
'''
IP地址归属地的自动查询
'''
url = "http://m.ip138.com/ip.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("爬取失败")
- 爬取猫眼电影 top 100
https://maoyan.com/board/4?offset=0
import threading
import requests, csv
from lxml import etree
"""
lxml 模块
requests 模块
csv 模块
python爬取猫眼电影 top 100 保存到CSV
"""
with open('data.csv', 'a', newline='') as f:
spamwriter = csv.writer(f)
spamwriter.writerow(['title', 'star', 'date', 'score'])
class Crawler(threading.Thread):
def __init__(self, page):
super().__init__()
self.page = page
def run(self):
# 模拟浏览器
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64)'
' AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}
# 网址 https://maoyan.com/board/4?offset=0
url = 'http://maoyan.com/board/4?offset={}'.format(10 * self.page)
response = requests.get(url, headers=headers)
html = etree.HTML(response.text)
# 获取该节点数据
results = html.xpath('//*[@class="board-wrapper"]/dd/div/div')
for result in results:
# 电影名称 电影主演 电影上映日期 评分
ws = [
result.xpath('./div[1]/p[1]/a/text()')[0],
result.xpath('./div[1]/p[2]/text()')[0].strip(),
result.xpath('./div[1]/p[3]/text()')[0],
result.xpath('./div[2]/p/i[1]/text()')[0] + result.xpath('./div[2]/p/i[2]/text()')[0],
]
print(ws)
# 保存到CSV
with open('data.csv', 'a', newline='') as f:
writer = csv.writer(f)
writer.writerow(ws)
if __name__ == '__main__':
# 指定页数
for page in range(10):
th = Crawler(page)
th.start()