python爬虫基础知识

来源:互联网 发布:c语言捕鱼 编辑:程序博客网 时间:2024/04/30 08:27
  1. 爬虫基本知识
  • 基本流程:网站-爬虫程序-本地存储(让爬虫程序伪装成一个浏览器去请求,而不是一个程序在跑)
  • 日常操作中打开网页流程

输入网站URL,按回车键-浏览器发送请求至远程服务器-远程服务器返回数据-浏览器渲染页面展示出合适的页面

  • URL基本知识

传输协议(HTTPHTTPSFTP等):一个冒号,两个斜杠

主机(通常是一个域名,也有是IP的);

端口(服务器上网络端口号,默认80,可选项);

路径(以“/”开头的一个文件路径);

查询(以“&”开头的遗传查询参数,QueryString


  • 爬虫中常见 HTTP / HTTPS协议
    • 超文本传输协议( HTTP)的设计目是保证客户机与服务器之间通信。
    • HTTP的工作方式是客户机与服务器之间请求-应答协议。(无状态协议)

 

  1. 爬虫中常见 HTTP / HTTPS方法
  • GET请求
    • 从指定的资源请求数据
    • 请注意,查询字符串(名称 /值对)是在GET请求的URL中发送的
  • POST请求
    • 向指定的资源提交要被处理的数据
    • 请注意,查询字符串(名称 /值对)是在POST请求的HTTP消息主体中发送的
  • 一点点GET / POST 区别
  • HTTP的底层是 TCP/IP,所以 GETPOST的底层也是 TCP/IP ,也就是说GET/POST都是TCP链接。GETPOST能做的事情是一样。你要给GET加上 request body,给 POST带上 url参数,技术上是完全行的通。(GET传递数据时是可见的,GET的所有数据在URL中能够看见,都可以被复制粘贴出来;POST的数据是隐藏的,需要一些抓包的程序把数据拿到)
  • 首先引入一个副作用的概念,副作用指当你发送完一个请求以后,网站上的资源状态没有发生修改,即认为这个请求是无副作用的。比如注册用户这个请求是有副作用的,获取用户详情可以认为是无副作用的。再引入一个幂等性的概念,幂等是说,一个请求原封不动的发送N次和M次(N不等于MNM都大于1)服务器上资源的状态最终是一致的。比如发贴是非幂等的,重放10次发贴请求会创建10个帖子。但修改帖子内容是幂等的,一个修改请求重放无论多少次,帖子最终状态都是一致的。POST/PUT 请求可以通过传递 request body来发送大量的数据,而 GET/DELETE不能。

GET:无副作用,幂等,不可带 Request Body

POST:副作用,非幂等,可以带 Request Body

 

  1. 常用的状态码


200OK):找到了该资源,并且一切正常。

304NOT MODIFIED:该资源在上次请求之后没有任何修改,这通常用于浏览器的缓存机制。

401(UNAUTHORIZED):客户端无权访问该资源,这通常会使得浏览器要求用户输入用户名和密码,以登陆到服务器。

403(FORBIDDEN):客户端未能获得授权,这通常是在401之后输入了不正确的用户名或密码。

404(NOT FOUND):在制定的位置不存在所申请的资源。

 

  1. HTML基本知识
  • 树状结构


 

  • 浏览器中 HTML页面渲染流程
  1. 用户输入网址(假设是个 html页面,并且是第一次访问),浏览器向服务器发出请求,服务器返回 html文件;
  2. 浏览器开始载入html代码,发现 <head>标签内有一个 <link>标签引用部CSS文件;
  3. 浏览器又发出 CSS文件的请求,服务器返回这个 CSS文件;
  4. 浏览器继续载入html<body>部分的代码,并且CSS文件已经拿到手了,可以开始渲染页面了;
  5. 浏览器在代码中发现一个 <img >标签引用了一张图片,向服务器发出请求。此时浏览器不会等到图片下载完,而是继续渲染后面的代码;
  6. 服务器返回图片文件,由于图片占用了一定面积,影响了后面段落的排布,因此浏览器需要回过头来重新渲染这部分代码;
  7. 浏览器发现了一个包含一行 Javascript代码的 <script> 标签,赶快运行它;
  8. Javascript脚本执行了这条语句,它命令浏览器隐藏掉代码中的某个<div> (style.display =”none” )。杯具啊,突然就少了这么一个元素浏览器不得重新渲染这部分代码
  9. 终于等到了</html>的到来。
  10. , 还没完用户点了一下界面中的“换肤”按钮,Javascript让浏览器换了一下 <link> 标签的 CSS 路径;
  11. 浏览器召集了在座的各位 <div><span>< ul ><li> 们,“大伙儿收拾行李,咱得重新来过 ……”,浏览器向服务请求了新的 CSS 文件,重新渲染页面

 

  1. Python Requests

参考Request官方手册,在线地址:

http://docs.python-requests.org/zh_CN/latest/user/quickstart.html

 

  • 发送请求:

#使用 Requests 发送网络请求非常简单。一开始要导入 Requests 模块:import requests#然后,尝试获取某个网页。本例子中,我们来获取知乎日报:daily_url='http://daily.zhihu.com/'r = requests.get(daily_url)#现在,我们有一个名为r的Response(响应内容)对象,我们可以从这个对象中获取所有我们想要的信息。r.text#Requests 会自动解码来自服务器的内容。大多数 unicode 字符集都能被无缝地解码。请求发出后,Requests 会基于 HTTP头部对响应的编码作出有根据的推测。当你访问 r.text之时,Requests会使用其推测的文本编码。你可以找出 Requests 使用了什么编码,并且能够使用 r.encoding 属性来改变它:r.encoding'utf-8'r.encoding = 'ISO-8859-1'#查看方法:dir(r)

  • 响应内容:我们能读取服务器响应的内容。

JSON响应内容(如果返回的是JSON数据)

Requests 中也有一个内置的 JSON 解码器,助你处理 JSON 数据import requestsr = requests.get('https://github.com/timeline.json')r.json()[{u'repository':{u'open_issues': 0, u'url': 'https://github.com/...

#如果 JSON 解码失败,r.json 就会抛出一个异常。例如,相应内容是 401 (Unauthorized),尝试访问 r.json 将会抛出 ValueError: NoJSON object could be decoded 异常。

  • 提取数据:

数据在被接收之后呈现HTML原始数据的结构,包含大量我们不需要原始数据的结构,这里我们使用BS4去解释HTML数据通过 BS4 放回的数据结构数据,提取所需要的数据

BS4的官方文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html

Beautiful Soup是一个可以从HTML或XML文件中提取数据的Python库它能够通过你喜欢的转换器实现惯用的文档导航查找修改文档的方式Beautiful Soup会帮你节省数小时甚至数天的工作时间。(如果写正则很费事)

BS4中的Beautiful主要功能就是将符合HTML页面结构的字符串格式化成HTML树状结构;再从格式化的树状结构中提取数据

  • 查找:findfind_all函数
  1. 相同点:都是从树状结构总搜索出符合条件的元素并返回
  2. 不同点:find_all会返回所有符合条件的元素,返回可迭代的结构(需要用for语句才能print);find则只会返回一个符合条件的元素的,返回字符串
  3. 代码示例:

#引入 BS4 包from from bs4 import BeautifulSoup#格式化字符串数据为BS4树状结构数据text_soup = BeautifulSoup(r.text, 'lxml')#从BS4 对象中搜索并返回符合条件的元素link_list= text_soup.find_all('a', attrs={'class':'link-button'})

  • 复杂的 POST 请求

通常,你想要发送一些编码为表单形式的数据——非常像一个 HTML 表单。要实现这个,只需简单地传递一个字典给 data 参数。你的数据字典在发出请求时会自动编码为表单形式

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

  • 实例:

# coding: utf-8import requestsfrom bs4 import BeautifulSoup#引入包 daily_url = 'http://daily.zhihu.com'  #请求的链接headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64;rv:49.0) Gecko/20100101 Firefox/49.0'}  #请求的头r = requests.get(daily_url,headers=headers)#发起请求,get请求拿到的数据,本质上和查看网页源代码的数据是一模一样的text_soup = BeautifulSoup(r.text, 'lxml')  #请求的结果格式化成BeautifulSoup link_list = text_soup.find_all('a', attrs={'class':'link-button'})#想要得到每篇文章背后对应的链接,拿到a链接,寻找link-button标签,拿到所有符合条件的链接 f = open('daily_content.txt', 'a+', encoding='utf8')#通过循环一个个拿到文章链接以及解析内容for link in link_list:    daily_content_url =daily_url + link['href'] #域名+路径为网址,拿到每一页的链接    daily_content_page =requests.get(daily_content_url, headers=headers) #请求子页面    daily_content_soup =BeautifulSoup(daily_content_page.text, 'lxml')#通过链接拿到每一页的正文内容    daily_content =daily_content_soup.find('div', attrs={'class':'answer'})#子网页内容,find找到第一个就停止了    f.write('{url:'+daily_content_url + '},{title:' + link.text + '},[' +daily_content.text.strip() + ']')    breakf.close() login_url = 'https://www.zhihu.com/login/email'post_data = {    'password':'shen147258',    'captcha_type':'cn',    'email':'454900743@qq.com'}login_page = requests.post(login_url, headers=headers,data=post_data)#必须带header才会认为不是爬虫?

 

 

  1. Cookies简介
  • Cookies是什么?

Cookies是一小段文本信息,伴随着用户请求和页面在Web服务器和浏览器之间传递,Cookies包含每次用户访问站点时Web应用程序都可以读取的信息。

  • 为什么需要Cookies?

因为HTTP协议是无状态的,对于一个浏览器发出的多次请求,WEB服务器无法区分是不是来源于同一个浏览器。所以,需要额外的数据用于维护会话。Cookies正是这样的一段随HTTP请求一起被传递的额外数据。

  • Cookies能做什么?

Cookies只是一段文本,所以它只能保存字符串。而且浏览器对它有大小限制以及它会随着每次请求被发送到服务器,所以应该保证它不要太大。Cookies的内容也是明文保存的,有些浏览器提供界面修改,所以,不适合保存重要的或者涉及隐私的内容。(保存很小一段字符串,访问的凭据,所有请求都会带有Cookies但是某些情况下不验证cookies的,需要验证的时候必须给出cookies才会返回数据)

  • Cookies简单实例

模拟知乎登陆,并获取登陆之后才能获取到的数据

login_page.cookiesexplore_url = 'https://www.zhihu.com/node/ExploreAnswerListV2?params={"offset":%d,"type":"day"}'   #URL解码工具解码可以得到# 5 ,10 ,20 ,25# https://www.zhihu.com/node/ExploreAnswerListV2?params={"offset":%d,"type":"day"}print(explore_url % 5 )#然后重复上述请求过程login_page = requests.get(explore_url % 5,                          headers=headers,                          cookies=login_page.cookies                           ) login_page.text

 

  1. 小结

分析页面的请求拿到需要的数据,数据是从服务器来的,那么客户端发起请求到服务器,才会服返回数据;动态爬虫其实是本地的某段JS被触发,从服务器上拿数据返回回来,可以通过python代码模拟JS行为发起请求,也就实现动态爬虫的功能。服务器只管接收http请求,javascript可以发起这个请求,python也可以,只要python发起的请求和JS发起的请求时一模一样的,那么就无法分辨到底是JS请求还是python请求,从而实现动态爬虫。

2 0
原创粉丝点击