python爬虫获取方法_小白学python爬虫:2.获得数据
在上一篇文章我我们已经完成了对网页的分析,包括了:在源码中数据的定位;获取方法(xpath)。那么在获得数据之前我们考虑的则是如何获取源码。
接下来我们将学习如何从服务器获得源码。
#写在前面“上网”的底层原理
获得源码(获得服务器响应更为准确)是爬虫最重要的一步。本文将会为大家说明python爬虫发起请求的正确姿势。
2.1 一些专业名词
url:Uniform Resource Locator(统一资源定位符),也就是我们常说的网址。“统一”即代表它的名称是有一定规则的。第一部分:http,它是协议名称,什么是协议呢?协议中规定了一系列在我们与服务器对话中的一些规范,说通俗点,你可以把它想象成一个关于客户端与服务器对话之间的一个合同,在这个合同中规定了两方在对话过程中应该遵守的一些方法或规则。我会在后文进行详细介绍。
第二部分:服务器名称,通常是介于“//”和第一个“/”之间,在本例中,则是"www.w3school.com.cn"。你可以把服务器想象一台电脑,服务器名称就是这台电脑的名称。
第三部分:文件存放路径部分,在本例中则是"/tags/html_ref_urlencode.html"。既然服务器是一台电脑,那么这个“电脑”里的文件肯定都有一个相对应的路径,是吧。
以“http”作为基本的“访问规范”,访问了“www.w3school.com.cn”这台“电脑”上的“/tags”这个路径下的“html_ref_urlencode.html”这个文件。
当然了,我举的这个例子只是相对基础、简单的一种形式。有一些部分为了方便大家理解,我适当的略去了,关于对url详细的讲解,有兴趣的同学可以看看这篇文章:url详解
服务器(host):这台“电脑”不单单是储存一些文件资源,它每天还要处理成千上万的访问。
客户端(user-agent):我们访问服务器的工具,一般来说就是我们每天用的浏览器。
2.2 与服务器“对话”
我们可以把每天的上网行为想象成是在与服务器进行“对话”,每当我们访问一个网址的时候,你与服务器的对话就开始了:当你对某一网址进行访问时,相当于你对这个网址的服务器说:我想要你XX路径下的XX资源
当服务器收到你的请求后,判断是否接受你这个请求(比如说有些东西是要你登录账户后才能给你的,这时候服务器就要判断你是否登录)
如果你符合要求,服务器将会返回你所请求的资源
而这一套流程(我省略了一些细节部分)的一些规则、方法,则是由上文提到的通信协议所制定的。我们常见的协议有两种:http和https。其中https是在http的基础上对增加了对话内容进行加密的一个流程。所以我们在这里只为大家介绍http。
2.2.1 “对话”的协议:http
http:Hyper Text Transfer Protocal(超文本传输协议)
这个协议规定了我们与服务器对话常用的两种方式:post和get
post是向服务器提交数据例如我们注册账号的时候会输入手机号,用户名,密码等信息,这其实就是一个post方法,将你的账号信息提交给服务器并由服务器存储
还有一种是你向服务器提交一些信息,而服务器则返回相应的内容,常见的有网页上的在线翻译。这里我们可以用python实现在线翻译。我会在下文给出代码
get是向服务器“索要”资源get就是按照上文说到的url来定位资源位置然后返回相应的资源
这个是我们最常用的一个方法,在上一篇文章的实战中我们就是用get方法获得了含有评论的html文档
这个协议也规定了我们与服务器对话时需要的一些信息:http header(http头部信息)
network会记录浏览器与服务器之间传输的所有文件,你可以看到html_ref_urlencode.html就在其中。看到这可能有些同学会好奇,为啥还有几个png(图片)?这是因为html文档中对这几个图片进行了引用(上一篇文章中的标签的src属性),所以当你请求这个html文档时,该文档引用的图片也会同时返回给你。
我们点击那个html文档,就能够看见header信息了
一般来说,http头部信息可以分成3个部分:general header:指出此次对话的一些概要信息。一般的,其中会包含要访问的url,对话方法(post或者get),stauts code(服务器响应状态码,常见的有200(成功),403(服务器拒绝),404(请求的资源不存在))等
response header:关于服务器的一些信息。一般的,其中会包含server(服务器种类)等
request header:关于客户端的一些信息。一般的,其中会包含accept(定义我们愿意接受服务器传给我们的资源的类型,例如说text/html则是告诉服务器我们可以接受text/htm类型的资源),accept-encoding(资源的编码类型),accept-language(可接受的语言),host(指定请求的服务器名称),user-agent(你是通过哪个浏览器来访问)等
根据上面的图片,大家应该可以猜出这些header的作用:告诉对方我要什么,能够接受什么,我这次对话的状态是啥样的,以及一些对话的详细信息。
其实对于我们爬虫来说,我们需要重点关注request header的几个值,我会在下面详细说明。
下面我会举两个例子帮助大家理解以上两个知识点:对话方法和对话的头部信息
#例1:get方法
import requests
url = "http://www.w3school.com.cn/tags/html_ref_urlencode.html"
header = {"accept":"image/webp,image/apng"}#python能够以字典的格式定制request header信息
r = requests.get(url,headers=header)#使用get方法请求资源
r.status_code#查看相应状态码
Out[181]: 406
header = {"accept":"text/html"}
r = requests.get(url,headers=header)
r.status_code
Out[184]: 200
你可以看到,当我们传递给服务器两种不同的accept值的时候,服务器的响应是不同的。第一个header告诉服务器我只接受图片类型的资源,但是我请求的资源是一个html文档。所以会出现406错误
如果我将第一次请求的资源换成图片呢?
r = requests.get("http://www.w3school.com.cn/ui2017/wrapper.png",headers={"accept":"image/png"})
r.status_code
Out[196]: 200
所以说request header的值能够影响服务器返回给我们的响应。
#例2:post方法
接下来我们试试post方法,以在线翻译为目标:我们向服务器post想要翻译的内容,服务器返回相应的翻译。打开有道翻译:在线翻译_有道
进入开发者工具,选择network
在右侧输入要翻译的文本,然后在右侧的network中点击我用红色方框标记出来的项
看到这一步你可能有几个疑问:
以上两个问题中包含了两个我还没有提及的知识点:url的参数查询
xhr异步加载
这两点我会在后面详细讲解,现在主要是感受一下post方法
import requests
url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
#从network的form data中复制下来的我们要post的参数
row_data = '''i: 你好from: AUTOto: AUTOsmartresult: dictclient: fanyideskwebsalt: 1535363854099sign: 014c7769cdecc9134307ac6dbf89bb2cdoctype: jsonversion: 2.1keyfrom: fanyi.webaction: FY_BY_REALTIMEtypoResult: false'''
post_data = {}
#将psot参数处理成字典类型
for each in row_data.split("\n"):
key,value = each.split(":",1)
post_data[key] = value.replace(" ","")
header = {}从network的request header中复制下来的header参数
row_header = '''Accept: application/json, text/javascript, */*; q=0.01Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Connection: keep-aliveContent-Length: 214Content-Type: application/x-www-form-urlencoded; charset=UTF-8Cookie: _ga=GA1.2.50802496.1533625637; OUTFOX_SEARCH_USER_ID_NCOO=1577126772.4247394; OUTFOX_SEARCH_USER_ID=241799813@10.169.0.83; JSESSIONID=aaaPu5I3Doogc8yim06vw; ___rl__test__cookies=1535363854080Host: fanyi.youdao.comOrigin: http://fanyi.youdao.comReferer: http://fanyi.youdao.com/User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36X-Requested-With: XMLHttpRequest'''
for each in row_header.split("\n"):
key,value = each.split(":",1)
header[key] = value.replace(" ","")
r = requests.post(url,data=post_data,headers=header)
import json
content = json.loads(r.content)#因为返回的内容是json格式的数据
print(content)
{'translateResult': [[{'tgt': 'hello', 'src': '你好'}]], 'errorCode': 0, 'type': 'zh-CHS2en', 'smartResult': {'entries': ['', 'hello\r\n', 'hi\r\n'], 'type': 1}}
这里要提一点,header必须要用重新定制的(也就是从开发者工具上复制过来的request header),否则会返回以下内容,原因大家可以自己去测试一下是缺少了哪个header值。因为不用的网址可能对header有不同的要求,我曾经爬过一个网址要求必须有refer值。。。
所以在实战中,大家尽可能将header全部复制替换过去。但要注意accept值的范围,因为如果你接受压缩包格式的数据的话,会解析成乱码的。
r = requests.post(url,data=post_data)
content = json.loads(r.content)
print(content)
{'errorCode': 50}
通过以上两个例子,我们应该可以直观的感受get方法和post方法的作用与结果了。
接下来我们来重点说request header中的几个关键的值
User-Agent:这个值表示你是用哪种“工具”去访问的服务器,下面的代码是requests的源码,可以看到默认的header中的user-agent是“python-requests”加上版本号,有些服务器看到这个user-agent可能会拒绝你的请求,因为你这是告诉服务器我是爬虫,而服务器不想被爬虫访问而造成资源的占用或者其因为其他的原因去拒绝你的访问。
所以我们可以将user-agent替换成浏览器的,这样你就是批着浏览器的“皮”去访问服务器
cookies:如果你爬的网址需要登录才能访问,那么一般情况下,在header中加入cookies这一值就能够让服务器判断你是处于登录状态。具体原理我就不在这讲了,因为我也不知道。
def default_user_agent(name="python-requests"):
""" Return a string representing the default user agent. :rtype: str"""
return'%s/%s'% (name, __version__)
def default_headers():
""" :rtype: requests.structures.CaseInsensitiveDict"""
return CaseInsensitiveDict({'User-Agent': default_user_agent(),
'Accept-Encoding': ', '.join(('gzip', 'deflate')),
'Accept': '*/*',
'Connection': 'keep-alive', })
关于如何使用requests定制request header(请求头)可以参考:快速上手 - Requests 2.18.1 文档
#实战:伪装成浏览器访问并登陆知乎
import requests
url = 'https://www.zhihu.com'
r = requests.get(url)
r.status_code
Out[415]: 400
使用默认requests的默认header的话直接是400(bad request)
header = {}
row_header = '''accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
accept-language: zh-CN,zh;q=0.9
cache-control: max-age=0
cookie: 省略。。这个不能贴出来
referer: https://www.zhihu.com
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36'''
for each in row_header.split('\n'):
key,value = each.split(":",1)
header[key] = value.replace(" ","")
loged_r = requests.get(url,headers=header)
html = loged_r.content.decode(loged_r.encoding)
loged_r.status_code
Out[416]: 200
大家可以把html复制到txt让改成html后缀,再用浏览器打开,可以看到自己的头像哦
以上
欢迎大家评论,一起进步
python爬虫获取方法_小白学python爬虫:2.获得数据相关推荐
- python 使用socks 爬虫_小白学 Python 爬虫(17):Requests 基础使用
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- post python爬虫_小白学 Python 爬虫(17):Requests 基础使用
人生苦短,我用 Python 如果我的文章对您有帮助,请关注支持下作者的公众号:极客挖掘机,您的关注,是对小编坚持原创的最大鼓励:) 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Py ...
- python 爬虫框架_小白学 Python 爬虫(28):自动化测试框架 Selenium (下)
人生苦短,我用 Python 如果我的文章对您有帮助,请关注支持下作者的公众号:极客挖掘机,您的关注,是对小编坚持原创的最大鼓励:) 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Py ...
- python判断素数_小白学Python | 你还在说你入不了门吗
收藏的好多啊 原创不易,动动小手,点个赞啦!! 十二月份,天气有时候会很阴沉,一天都见不到太阳.气温也慢慢变冷了,晚上回家还是会感觉到衣服穿少了. 阴阴沉沉总会过去的,我还是期待阳春三月. 2019年 ...
- ora-00923数据类型不一致_小白学 Python(2):基础数据类型(上)
如果我的文章对您有帮助,请关注支持下作者的公众号:极客挖掘机,获取最新干货推送:) 人生苦短,我选Python 引言 前文传送门 小白学 Python(1):开篇 接触一门新的语言,肯定要先了解它的基 ...
- matplotlib plot 分组_小白学 Python 数据分析(16):Matplotlib(一)坐标系
人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...
- logback-spring.xml 文件路径 相对路径_小白学 Python(18):基础文件操作
人生苦短,我选Python 前文传送门 小白学 Python(1):开篇 小白学 Python(2):基础数据类型(上) 小白学 Python(3):基础数据类型(下) 小白学 Python(4):变 ...
- python 相对路径报错_小白学 Python(18):基础文件操作
人生苦短,我选Python 前文传送门 小白学 Python(1):开篇 小白学 Python(2):基础数据类型(上) 小白学 Python(3):基础数据类型(下) 小白学 Python(4):变 ...
- 女生学python好就业吗-新手小白学Python有前途吗
很多同学在选择学习python之初,可能都有这样的疑惑:学Python有前途吗?对于新兴的事物,人们慢慢接受是需要一个过程的,那究竟学python有没有前途呢?今天北大青鸟小编就来给大家指导一下迷津. ...
最新文章
- python的虚拟环境
- Jmeter之配置元件操作
- openstack 管理三十五 - 利用 SQL 获取 tenant 当前资源情况
- 2019游戏 f1_2019年F1中国大奖赛激情开跑,这款手游带你体验真实F1的魅力
- spark需要maven管理吗_使用Eclipse编写Spark应用程序(Scala+Maven)
- 【优化充电】基于matlab蒙特卡洛算法求解电动汽车充电优化问题【含Matlab源码 1164期】
- async/await 异步编程(转载)
- Windows下Node_OneBot配置方法
- 设计一个递归算法释放二叉树bt中的所有结点(二叉树采用二叉链表存储结构)
- centos使用迅雷远程下载
- Hadoop完全分布式集群——Hadoop 配置
- 微信上传临时素材|微信公众号发送图片
- 十年老撕鸡分享,五分钟搭建个人轻论坛
- 用python爬取拉勾网招聘信息并以CSV文件存储
- pytho wordcloud安装
- 如何轻松学习C语言编程!
- 公司现有一个工作组workgroup,需要添加samba服务器作为文件服务器,并发布共享目录
- uM计算机组成原理,计算机组成原理_课程设计报告.doc
- 程序员必看!2021最新京东Java面试题目附详细答案解析
- 战队口号霸气押韵8字_校园运动会加油霸气押韵口号文案 2020最有特色的运动会口号...
热门文章
- 千灯照碧云,越夜越星沙
- 消费金融大潮来了,银行必须打出这套进攻+防守的组合拳
- java 左右两边数据类型不一样_Java笔记-day004-[运算符]
- gophp解释器_对比平台--Go和PHP之间的区别
- linux系统sql语句报错_如果数据库管理工具1045错误出现在Linux系统中怎么
- linux sysconf函数,linux c sysconf函数 得到系统配置
- python装饰器有几种_python几种装饰器的用法
- python用pip安装_使用pip安装python库的几种常用方法
- SQL语言之DQL语言学习(一) 基础查询
- linux 报错 E: 无法定位软件包 python-lzma