爬虫第一课——教你学会使用requests库
目录
前言
一、发送请求的一些方式
(一)GET
1.url
2.headers
3.proxies
4.timeout
5.params
6.verify
(二)POST
1.url
2. headers
3.data
4.json
二、对响应数据进行简单处理
(一)response.content
(二)response.apparent_encoding
(二)response.text
(三)response.status_code
1.常见的响应状态码:
2.注意事项
(四)response.request.headers
(五)response.headers
(六)response.url
(七)response.request._cookies
(八)response.cookies
1.将CookieJar类型转换为Cookie
2.将Cookie转换为CookieJar类型
3.将Cookie转换为Cookie字典
三、requests.session()的使用
四、爬虫小例子
(一)爬取实习僧职位信息
(二)百度图片下载
前言
在requests库可以说是爬虫中必备的一个第三方库(在python2版本中常用python的内置库urllib,在python3中也常用urllib库的一些模块方便开发)。
由于requests库是第三方库,所有需要安装
pip install requests
requests库是作用简单来说就是:向要爬取的目标网站发送请求,再获取网站的响应数据,然后可以对这些响应数据进行简单处理。
一、发送请求的一些方式
发送请求的方式有七种,爬虫常用的是GET和POST。
(一)GET
# [ ]表示里面的参数为可选参数
response=requests.get(url[, headers, proxies,timeout, params, verify])
下面对其中的参数进行一些详细说明
1.url
url为你要爬取的目标网站的链接,可以直接将url换成链接,也可以写url=目标网站链接
response=requests.get('http://www.baidu.com')
或者
response=requests.get(url='http://www.baidu.com')
2.headers
headers为请求头,也是网站反爬的重点,查看一个网站的请求头,可以打开目标网站,然后打开开发者工具(或按F12),然后选择Network,再刷新一下网页。这样就可以捕获到网站的请求和响应数据。通常选择左侧Name窗口的第一项,然后选择Headers,Request Headers,我们在爬虫中要添加的请求头都在里面。
爬虫请求头中最常添加的几个参数如下(直接把浏览器查到的对应项复制过来即可):
(1)Cookie
用于身份验证和登录的状态保持
(2)Host
目标网站的主机
(3)Referer
请求的来源,常用于防盗链
(4)User-Agent
请求代理,此项是最常见的反爬手段,因为爬虫程序会默认把此参数的值设置为Python啥啥啥,目标网站通过此参数可以判断该请求是否由爬虫程序发出
如果添加了这些参数还不能正常爬取,就尝试再复制添加几个其他的参数,如果全部参数都添加了依旧不能爬取,那么就要在其他方面“动手脚”。
添加方式为,定义一个字典,将以上参数添加到字典中,然后将headers=该字典,例如
headers_dict={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
}
response=requests.get(url,headers=headers_dict)
3.proxies
当访问一个网站时,你的电脑IP地址会被网站记录下来,如果你访问太过于频繁,网站可能会认定此IP来自一个爬虫程序或者网站遭到了攻击,此时就会把这个IP添加到网站访问的黑名单中,然后再去访问网站时就会什么都获取不到,一般来说IP被封禁后几天就会恢复,但是既然我们是做爬虫的,肯定要求一个时效性,怎么一直等待几天呢?这时就用到了proxies参数。
格式如下
proxies_data={
'https':'https://ip地址:端口号', # 用于https的网站
'http':'http://ip地址:端口号' # 用于http的网站
}
response=requests.get(url,proxies=proxies_data)
此时网站记录的就是你添加的IP地址,而不是你自己的电脑IP。
那么这些ip地址和端口号去哪获取呢?第一种方式是直接用浏览器搜索“ip代理”,有很多免费的代理可以选择,但是免费的缺点就是ip地址容易失效,不稳定,而且几乎没有https的;推荐使用付费的ip代理,稳定性比较高。
注意:当目标网站是http时,只有http的代理ip会生效;当目标网站是https时,只有https的代理ip会生效。
4.timeout
格式如下
response=requests.get(url,timeout=3)
作用就是当请求时间超过3秒还未获取到响应时,就会抛出异常,可以使用try...except处理异常。
5.params
用于添加发送get请求时传入的一些参数,可以在开发者工具---Network---Headers---Query String Parameters中看到。
例如我在百度的搜索框中输入“params参数”,然后搜索,然后打开开发者工具,刷新网页就能看到。
和添加headers一样,定义一个字典,字典中写入以上内容,然后再指定params=此字典即可。
注意:有些参数是每次访问时js算法生成的,直接复制过去没有用,这就需要学习一下JS逆向破解的内容。
6.verify
当浏览器访问网站出现这个提示时,使用爬虫程序请求此网站也会出错,出现这个问题的网站基本都是https的网站,是由于这个网站用到的安全证书已过期,或者这个安全证书是私人的证书,都会提示这个问题的,是网站的问题,不是你电脑或者爬虫的问题。
解决方式是将verify的值设置为False,表示爬虫程序不验证网站的安全证书,设置为False后爬虫可以正常请求网站,但是会出来一个警告信息(不影响程序运行)
可以使用如下代码去掉警告~
import urllib3
urllib3.disable_warnings()
response=requests.get(url,verify=False)
(二)POST
格式为
# [ ]表示里面的参数为可选参数
response=requests.post(url[, headers,data,json])
1.url
访问的目标网站链接(同get方法)
2. headers
请求头(同get方法)
3.data
当请求头中的Content-Type为application/x-www-form-urlencoded时,请求的参数,在开发者工具——Network——Headers——Form Data中。
添加的方式也是先定义一个字典,字典中添加Form Data中的内容,然后将data=此字典。
data_dict={
......
......
}
response=requests.post(url,data=data_dict)
4.json
当请求头中的Content-Type为application/json时,表明需要传的是一个json类型的对象,请求的参数,在开发者工具——Network——Headers——Request Payload中。
添加的方式也是先定义一个字典,注意是字典,不需要使用json模块的json.dumps()转成json格式!requests模块会自动转。然后字典中添加Request Payload中的内容,然后将json=此字典。
json_dict={
......
......
}
response=requests.post(url,json=json_dict)
二、对响应数据进行简单处理
(一)response.content
返回原生的响应内容,也就是没有经过任何解码的Byte类型的二进制数据,例如图片、视频、音频、文本等等。
(二)response.apparent_encoding
apparent_encoding会从网页的内容中分析网页编码的方式,可以将此值复制给response.encoding进行解码。
(二)response.text
将 response.content进行解码的字符串,requests会根据自己的猜测来判断采用哪种解码方式,所以有可能会猜测错误,导致页面产生乱码,这时候就应该使用自定义的解码方式来进行解码。 response.content.decode('utf-8'),表示以utf-8的编码方式进行解码,解码的结果为Unicode类型的字符串,也可以使用gbk、gb2312等编码方式,decode()函数的默认解码方式是utf-8。
只能解码文本数据,如果是图片、音视频等不行。
print(response.content.decode())
也可以这样写
response.encoding=response.apparent_encoding
print(response.text)
(三)response.status_code
返回响应的状态码。
1.常见的响应状态码:
200 | 请求成功 |
302 | 页面跳转,新的URL在响应头的Location参数中给出 |
303 | 浏览器对于POST的响应进行重定向至新的URL |
307 | 浏览器对于GET的响应重定向至新的URL |
403 | 资源不可用,服务器理解客户的请求,但是拒绝处理 |
404 | 请求的页面在服务器中未找到 |
500 | 服务器内部错误 |
503 | 服务器由于维护或负载过重未能应答,在响应头中可能会携带Retry-Afrer响应头;也可能是爬虫频繁访问导致服务器忽视爬虫的请求 |
2.注意事项
(1)所有的状态码都不可信(因为状态码也是网站的后端程序员写的!),一切都以是否能够抓包得到响应体中的数据为准!就是开发者工具的Network中获取的数据。
(2)一般来讲,如果网站的后端程序员讲武德,会把网站的响应状态码严格按照规定来写,此时应注意,如果response.status_code返回的状态码是4开头,就要尝试切换IP代理。
(四)response.request.headers
返回向网站发送请求时的请求头。
(五)response.headers
返回获取响应时的响应头。
(六)response.url
返回此响应对应的请求的URL。
(七)response.request._cookies
返回此响应对应的请求的Cookie,为CookieJar类型。
(八)response.cookies
返回此响应的Cookie,经过了Set-Cookie的动作,为CookieJar类型。
1.将CookieJar类型转换为Cookie
dict_cookies=requests.utils.dict_from_cookiejar(response.cookies)
print(dict_cookies)
2.将Cookie转换为CookieJar类型
jar_cookies=requests.utils.cookiejar_from_dict(dict_cookies)
print(jar_cookies)
3.将Cookie转换为Cookie字典
cookies_dict={cookie.split('=')[0]:cookie.split('=')[-1] for cookie in response.cookies.split('; ')}
三、requests.session()的使用
requests.session()用于会话保持。当使用session成功请求了某个网站,则再次使用此session对象请求该网站的其他网页时都会使用该session对象之前使用的Cookie等参数。
在请求某些网站时,需要登录才能够获取数据,我们不可能做到每请求一次都要去登陆一下,这样太过于繁琐,此时就需要用到session保持会话的功能了,我们可以只登陆一次,然后保持这种状态去完成更多的请求~
使用方法如下:
headers_dict={'referer': 'https://github.com/session','user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
}
my_session=requests.session()
my_session.headers=headers_dict
response=my_session.get(url)
设置了session之后,对网站的请求操作还是与之前的requests.get和requests.post一样,只是把requests换成了你自己设置的session对象名。如果headers等参数在定义session对象时已经统一设置过了,那么在get或者post请求中添加的headers等参数会把原来统一设置的headers等参数替换掉。
四、爬虫小例子
(一)爬取实习僧职位信息
import requests
from bs4 import BeautifulSoup
headers={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
}# 获取页面
def getPage(url):try:re=requests.get(url,headers=headers,timeout=5)re.encoding=re.apparent_encodingreturn re.textexcept:print('Error!')# 获取详细信息
def getDetail(html):soup=BeautifulSoup(html,'03lxml')# title=soup.title.text #获取网页标题job_name=soup.select('.new_job_name span')[0].text.strip()company_name=soup.select('.com_intro .com-name')[0].text.strip()salary=getNumber(soup.select('.job_money')[0].text.strip())job_week=getNumber(soup.select('.job_week')[0].text.strip())job_time=getNumber(soup.select('.job_time')[0].text.strip())# print("{:<20}{:<20}{:<10}{:<10}{:<10}".format(job_name,company_name,salary,job_week,job_time))print(job_name,company_name,salary,job_week,job_time)# 字符串解密
def getNumber(text):text=text.encode('utf-8')text = text.replace(b'\xee\xac\xb1', b'0')text = text.replace(b'\xee\x99\xbc', b'1')text = text.replace(b'\xef\x82\x81', b'2')text = text.replace(b'\xee\xb2\x99', b'3')text = text.replace(b'\xef\x97\x92', b'4')text = text.replace(b'\xef\x8e\x93', b'5')text = text.replace(b'\xef\x96\x9f', b'6')text = text.replace(b'\xee\xb8\xb4', b'7')text = text.replace(b'\xef\x9e\xb1', b'8')text = text.replace(b'\xef\xa1\x99', b'9')# 将utf-8的编码解码为字符串,不加这一句,文字和数字均是utf-8编码text = text.decode()return textif __name__ == '__main__':# print("{:<20}{:<20}{:<10}{:<10}{:<10}".format("职位名称", "公司名称", "薪资", "实习天数", "实习月数"))url="https://www.shixiseng.com/interns?page=1&type=intern&keyword=Python&city=北京"html_1=getPage(url)soup=BeautifulSoup(html_1,'03lxml')count=soup.select('.el-pager .number')[-1].text # 页数for i in range(1,int(count)+1):print(">>>开始爬取第{}页".format(i))url='https://www.shixiseng.com/interns?page={}&type=intern&keyword=Python&city=北京'.format(i)html=getPage(url) # 获取每个page的urlsoup=BeautifulSoup(html,'03lxml')for item in soup.select('.f-l .intern-detail__job a'):url_detail=item['href'] #每个职位的详细链接html=getPage(url_detail)getDetail(html)
(二)百度图片下载
import requests
from urllib import parse
from uuid import uuid4
import os
import timeheaders={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
}
session=requests.session()
session.headers=headers
num=0
def getPage(url):page=session.get(url)print(page.status_code)# print(page.json())page.encoding=page.apparent_encodingdata=page.json()['data'] # 列表for i in data[:-1]: # 因为最后一个是空的,所以取到倒数第二个元素img_url=i['hoverURL']print(img_url)imgDownload(img_url)# 下载图片
def imgDownload(url):if not os.path.exists('06_imgs'):os.makedirs('06_imgs')global numtry:content=session.get(url)with open('06_imgs/{}.jpg'.format(uuid4()),'wb') as f:for chunk in content.iter_content(225): # 每次下载225字节if chunk:f.write(chunk)num += 1print(">>>第{}张爬取成功.".format(num))except:print(">>>爬取失败.")if __name__ == '__main__':# num=0s=time.time()word=input("请输入关键词:")pages=input("请输入要爬取的页数,每页30张图片:")for page in range(int(pages)):url='https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&word='+parse.quote(word)+'&pn='+str((page+1)*30)getPage(url)print(time.time()-s)
爬虫第一课——教你学会使用requests库相关推荐
- Python网络爬虫第一课----Python网络爬虫基础《http和https协议》
Python网络爬虫第一课----Python网络爬虫基础<http和https协议> 一.HTTP协议 1.官方概念: HTTP协议是Hyper Text Transfer Protoc ...
- python中requests库的用途-数据爬虫(三):python中requests库使用方法详解
有些网站访问时必须带有浏览器等信息,如果不传入headers就会报错,如下 使用 Requests 模块,上传文件也是如此简单的,文件的类型会自动进行处理: 因为12306有一个错误证书,我们那它的网 ...
- 吴恩达 神经网络和深度学习 第一课 第四周(代码和库)
参考博客(主代码):https://blog.csdn.net/u013733326/article/details/79767169 下面是需要的库文件代码:testCases,dnn_utils_ ...
- Python 网络爬虫与信息获取(一)—— requests 库的网络爬虫
1. 安装与测试 进入 cmd(以管理员权限),使用 pip 工具,pip install requests 进行安装: 基本用法: >> import requests >> ...
- python requests的作用_Python爬虫第一课:requests的使用
requests模块的入门使用 注意是requests不是request. 1.为什么使用requests模块,而不是用python自带的urllib requests的底层实现就是urllib re ...
- html最快学会的方式,零基础HTML玩家的Bootstrap入门第一课(保证学会!)
零.前言 又看着熟悉的Bootstrap3的网站,想起去年自己刚来时举步维艰的学习过程,想着之前踩过的那些坑,感慨万千.最近团队融入了新鲜血液,本着薪火相传的原则,为了不让后面的人踩同样的坑,才有了这 ...
- 爬虫第一课:写爬虫的思路
什么是爬虫? 爬虫就是从网上获得数据,它是通过编程来实现的.对于非计算机专业的人来说,一提到编程两个字,可能就会觉得自己做不到.但其实并不是这样,编程就是通过写代码,来让计算机实现你的想法.你解决问题 ...
- python爬虫第一课 开发环境配置
一.Python3的安装 二.请求库的安装 1.requests的安装 直接pip安装:pip3 install requests 2.Selenium的安装 selenium是一个自动测试化工具,利 ...
- 《无聊教程●第一课●教你编一个牛逼的VBScript邮件发送器》
也许 地球上的你正在看他们的教程 但你不知道 在另一个银河 正上演的一场激烈的战争 那就是 ...... 桃花侠 大战 菊花怪 坑爹啊!! 嘛,没错以上内容皆与课程无关.... { 我发现我写基础.单 ...
最新文章
- Python学习笔记-模块介绍
- oracle rtrim(),Oracle ltrim() rtrim() 函数详细用法
- [转帖]jQuery框架学习第八天:ASP.NET jQuery实施方案
- 技术·融合·治理|众享链网试运行总结暨正式运行发布会预告
- 天才程序员之陨落:业余项目创业 Cloudflare,公司上市前患病失去自理能力
- 注意判断js中使用正则表达式的转义字符,到底是对谁进行转义!!!
- jacob将word转换为html
- 运算放大器仿真 matlab,利用Matlab分析运算放大器电路.doc
- linux常用命令小结
- python模板是什么意思_python – 这个模板中的正确包含路径是什么?
- 基于mvc设计模式下的商品管理平台
- 520情人节告白❤HTML+CSS+JavaScript实现抖音流动爱心
- 青柚文案:水果店青柚推广文案,水果青柚广告文案
- 常用git 命令备忘
- node+vue微信小程序的社区后勤报修系统
- 报告:非洲加密货币诈骗活动比例低于世界其他地区
- 未能加载或程序集“XXXX,Version=0.0.0.0,Culter=neutral,PublicKeyToken=null”或它的某一个依赖项。试图加载格式不正确的程序。...
- 0x00000090 - 该内存不能read written
- 苹果地图副总裁_有关于苹果地图的几个新改变
- Android 在线预览ppt、doc、xls、txt等文件