爬虫-上

时间:2019-11-25 16:24:56   收藏:0   阅读:80

 

爬虫基础

网络爬虫

  网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。

另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫

#1、什么是互联网?
    互联网是由网络设备(网线,路由器,交换机,防火墙等等)和一台台计算机连接而成,像一张网一样。

#2、互联网建立的目的?
    互联网的核心价值在于数据的共享/传递:数据是存放于一台台计算机上的,而将计算机互联到一起的目的就是为了能够方便彼此之间的数据共享/传递,否则你只能拿U盘去别人的计算机上拷贝数据了。

#3、什么是上网?爬虫要做的是什么?
    我们所谓的上网便是由用户端计算机发送请求给目标计算机,将目标计算机的数据下载到本地的过程。
    #3.1 只不过,用户获取网络数据的方式是:
      浏览器提交请求->下载网页代码->解析/渲染成页面。

```
#3.2 而爬虫程序要做的就是:
  模拟浏览器发送请求->下载网页代码->只提取有用的数据->存放于数据库或文件中
 
#3.1与3.2的区别在于:
```

      我们的爬虫程序只提取网页代码中对我们有用的数据

 

总结爬虫

 #4.1 爬虫的比喻:
      如果我们把互联网比作一张大的蜘蛛网,那一台计算机上的数据便是蜘蛛网上的一个猎物,而爬虫程序就是一只小蜘蛛,沿着蜘蛛网抓取自己想要的猎物/数据

```
#4.2 爬虫的定义:
```

      向网站发起请求,获取资源后分析并提取有用数据的程序 

```
#4.3 爬虫的价值:
  互联网中最有价值的便是数据,比如天猫商城的商品信息,链家网的租房信息,雪球网的证券投资信息等等,这些数据都代表了各个行业的真金白银,
可以说,谁掌握了行业内的第一手数据,谁就成了整个行业的主宰,如果把整个互联网的数据比喻为一座宝藏,那我们的爬虫课程就是来教大家如何来高效地挖掘这些宝藏
,掌握了爬虫技能,你就成了所有互联网信息公司幕后的老板,换言之,它们都在免费为你提供有价值的数据。

 

爬虫的基本流程

技术分享图片

解析:

#1、发起请求
使用http库向目标站点发起请求,即发送一个Request
Request包含:请求头、请求体等

#2、获取响应内容
如果服务器能正常响应,则会得到一个Response
Response包含:html,json,图片,视频等

#3、解析内容
解析html数据:正则表达式,第三方解析库如Beautifulsoup,pyquery等
解析json数据:json模块
解析二进制数据:以b的方式写入文件

#4、保存数据
数据库
文件

 HTTP协议的请求与响应

http是什么?

  超文本传输协议(HyperText Transfer Protocol)

http协议的组成?

  Http协议由Http请求和Http响应组成。没有请求就没有响应。

#http协议:http://www.cnblogs.com/linhaifeng/articles/8243379.html

#Request:用户将自己的信息通过浏览器(socket client)发送给服务器(socket server)

#Response:服务器接收请求,分析用户发来的请求信息,然后返回数据(返回的数据中可能包含其他链接,如:图片,js,css等)

#ps:浏览器在接收Response后,会解析其内容来显示给用户,而爬虫程序在模拟浏览器发送请求然后接收Response后,是要提取其中的有用数据。

 

Request

#1、请求方式:
    常用的请求方式:GET,POST
    其他请求方式:HEAD,PUT,DELETE,OPTHONS

```
ps:用浏览器演示get与post的区别,(用登录演示post)

post与get请求最终都会拼接成这种形式:k1=xxx&k2=yyy&k3=zzz
post请求的参数放在请求体内:
    可用浏览器查看,存放于form data内
get请求的参数直接放在url后
```

#2、请求url
    url全称统一资源定位符,如一个网页文档,一张图片
    一个视频等都可以用url唯一来确定

```
url编码
https://www.baidu.com/s?wd=图片
图片会被编码(看示例代码)
```

```
网页的加载过程是:
加载一个网页,通常都是先加载document文档,
在解析document文档的时候,遇到链接,则针对超链接发起下载图片的请求
```

#3、请求头
    User-agent:请求头中如果没有user-agent客户端配置,
    服务端可能将你当做一个非法用户
    host
    cookies:cookie用来保存登录信息

```
一般做爬虫都会加上请求头
```

#4、请求体
    如果是get方式,请求体没有内容
    如果是post方式,请求体是format data

```
ps:
1、登录窗口,文件上传等,信息都会被附加到请求体内
2、登录,输入错误的用户名密码,然后提交,就可以看到post,正确登录后页面通常会跳转,无法捕捉到post 
```

 

技术分享图片

Response

#1、响应状态
    200:代表成功
    301:代表跳转
    404:文件不存在
    403:权限
    502:服务器错误

#2、Respone header
    set-cookie:可能有多个,是来告诉浏览器,把cookie保存下来
    
#3、preview就是网页源代码
    最主要的部分,包含了请求资源的内容
    如网页html,图片
    二进制数据等

技术分享图片

 

总结

#1、总结爬虫流程:
    爬取--->解析--->存储

#2、爬虫所需工具:
    请求库:requests,selenium
    解析库:正则,beautifulsoup,pyquery
    存储库:文件,MySQL,Mongodb,Redis

#3、爬虫常用框架:
    scrapy
复制代码

 

请求库之requests库

# import requests

 

简介

介绍:使用requests可以模拟浏览器的请求,比起之前用到的urllib,requests模块的api更加便捷(本质就是封装了urllib3)

#注意:requests库发送请求将网页内容下载下来以后,并不会执行js代码,这需要我们自己分析目标站点然后发起新的request请求

#安装:pip3 install requests

#各种请求方式:常用的就是requests.get()和requests.post()
>>> import requests
>>> r = requests.get(https://api.github.com/events)
>>> r = requests.post(http://httpbin.org/post, data = {key:value})
>>> r = requests.put(http://httpbin.org/put, data = {key:value})
>>> r = requests.delete(http://httpbin.org/delete)
>>> r = requests.head(http://httpbin.org/get)
>>> r = requests.options(http://httpbin.org/get)

 

基于GET的请求

1、基本的get请求

import requests
response=requests.get(http://dig.chouti.com/)
print(response.text)

 

2、带参数的get请求-->>>params

#在请求头内将自己伪装成浏览器,否则百度不会正常返回页面内容
import requests
response=requests.get(https://www.baidu.com/s?wd=python&pn=1,
                      headers={
                        User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36,
                      })
print(response.text)



#如果查询关键词是中文或者有其他特殊符号,则不得不进行url编码
乱码则修编码格式:encoding=‘utf-8‘
from urllib.parse import urlencode wd=‘jack老师 encode_res=urlencode({k:wd},encoding=utf-8) keyword=encode_res.split(=)[1] print(keyword)
# 然后拼接成url url=https://www.baidu.com/s?wd=%s&pn=1 %keyword response=requests.get(url, headers={ User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36, }) res1=response.text

 

params参数的作用

#上述操作可以用requests模块的一个params参数搞定,本质还是调用urlencode
from urllib.parse import urlencode
wd=jack老师
pn=1

response=requests.get(https://www.baidu.com/s,
                      params={
                          wd:wd,
                          pn:pn
                      },
                      headers={
                        User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36,
                      })
res2=response.text

#验证结果,打开a.html与b.html页面内容一样
with open(a.html,w,encoding=utf-8) as f:
    f.write(res1) 
with open(b.html, w, encoding=utf-8) as f:
    f.write(res2)

 

3、带参数的get请求-->>headers 请求体

#通常我们在发送请求时都需要带上请求头,请求头是将自身伪装成浏览器的关键,常见的有用的请求头如下
Host
Referer #大型网站通常都会根据该参数判断请求的来源
User-Agent #客户端
Cookie #Cookie信息虽然包含在请求头里,但requests模块有单独的参数来处理他,headers={}内就不要放它了

 

模仿浏览器请求,让服务端无法辨别是人为请求,不进行阻拦。

#添加headers(浏览器会识别请求头,不加可能会被拒绝访问,比如访问https://www.zhihu.com/explore)
import requests
response=requests.get(https://www.zhihu.com/explore)
response.status_code #500


#自己定制headers
headers={
    User-Agent:Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36,

}
respone=requests.get(https://www.zhihu.com/explore,
                     headers=headers)
print(respone.status_code) #200

 

4、带参数的get请求-->>>cookies

#登录github,然后从浏览器中获取cookies,以后就可以直接拿着cookie登录了,无需输入用户名密码
#用户名:egonlin 邮箱378533872@qq.com 密码lhf@123

import requests

Cookies={   user_session:wGMHFJKgDcmRIVvcA14_Wrt_3xaUyJNsBnPbYzEL6L0bHcfc,
}

response=requests.get(https://github.com/settings/emails,
             cookies=Cookies) #github对请求头没有什么限制,我们无需定制user-agent,对于其他网站可能还需要定制

print(378533872@qq.com in response.text) #True

 

基于POST请求

1、简介

#GET请求
HTTP默认的请求方法就是GET
     * 没有请求体
     * 数据必须在1K之内!
     * GET请求数据会暴露在浏览器的地址栏中

GET请求常用的操作:
       1. 在浏览器的地址栏中直接给出URL,那么就一定是GET请求
       2. 点击页面上的超链接也一定是GET请求
       3. 提交表单时,表单默认使用GET请求,但可以设置为POST

#POST请求
(1). 数据不会出现在地址栏中
(2). 数据的大小没有上限
(3). 有请求体
(4). 请求体中如果存在中文,会使用URL编码!

#!!!requests.post()用法与requests.get()完全一致,特殊的是requests.post()有一个data参数,用来存放请求体数据

 

2、发送post请求,模拟浏览器的登录行为

自动登录github(自己处理cookie信息)

‘‘‘
一 目标站点分析
    浏览器输入https://github.com/login
    然后输入错误的账号密码,抓包
    发现登录行为是post提交到:https://github.com/session
    而且请求头包含cookie
    而且请求体包含:
        commit:Sign in
        utf8:?
        authenticity_token:lbI8IJCwGslZS8qJPnof5e7ZkCoSoMn6jmDTsL1r/m06NLyIbw7vCrpwrFAPzHMep3Tmf/TSJVoXWrvDZaVwxQ==
        login:egonlin
        password:123



二 流程分析
    先GET:https://github.com/login拿到初始cookie与authenticity_token
    返回POST:https://github.com/session, 带上初始cookie,带上请求体(authenticity_token,用户名,密码等)
    最后拿到登录cookie

```
ps:如果密码时密文形式,则可以先输错账号,输对密码,然后到浏览器中拿到加密后的密码,github的密码是明文
```

‘‘‘

import requests
import re

#第一次请求
r1=requests.get(https://github.com/login)
r1_cookie=r1.cookies.get_dict() #拿到初始cookie(未被授权)
authenticity_token=re.findall(rname="authenticity_token".*?value="(.*?)",r1.text)[0] #从页面中拿到CSRF TOKEN

#第二次请求:带着初始cookie和TOKEN发送POST请求给登录页面,带上账号密码
data={
    commit:Sign in,
    utf8:?,
    authenticity_token:authenticity_token,
    login:317828332@qq.com,
    password:alex3714
}
r2=requests.post(https://github.com/session,
             data=data,
             cookies=r1_cookie
             )

login_cookie=r2.cookies.get_dict()

#第三次请求:以后的登录,拿着login_cookie就可以,比如访问一些个人配置
r3=requests.get(https://github.com/settings/emails,
                cookies=login_cookie)

print(317828332@qq.com in r3.text) #True

 利用requests.session()自动帮我们保持cookies信息

复制代码
import requests
import re

session=requests.session()
#第一次请求
r1=session.get(https://github.com/login)
authenticity_token=re.findall(rname="authenticity_token".*?value="(.*?)",r1.text)[0] #从页面中拿到CSRF TOKEN

#第二次请求
data={
    commit:Sign in,
    utf8:?,
    authenticity_token:authenticity_token,
    login:317828332@qq.com,
    password:alex3714
}
r2=session.post(https://github.com/session,
             data=data,
             )

#第三次请求
r3=session.get(https://github.com/settings/emails)

print(317828332@qq.com in r3.text) #True

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

正向代理

  所谓正向代理就是顺着请求的方向进行的代理,即代理服务器他是由你配置为你服务,去请求目标服务器地址。

例子:类似向黄牛购票,黄牛通过技术手段从官网获取余票再贩卖给你。

在举一个通俗的例子。你需要钱,C正好有钱,但是你C不直接借给你。你和B关系比较好,B可以找C借到钱。你和B沟通后,由B来找C借到钱后在给你。

技术分享图片

反向代理

  所谓反向代理正好与正向代理相反,代理服务器是为目标服务器服务的,虽然整体的请求返回路线都是一样的都是Client到Proxy到Server。

例子:在中介处咨询买房子,中介手里有很多房源再给你介绍进行买卖交易。

比如 我们访问百度网站,百度的代理服务器对外的域名为 https://www.baidu.com 。具体内部的服务器节点我们不知道。现实中我们通过访问百度的代理服务器后,代理服务器给我们转发请求到他们N多的服务器节点中的一个给我们进行搜索后将结果返回。

再举例:我们同样需要钱,但是我们又不知道谁有钱,所以我们找了一家网贷平台,你提交资料后,网贷平台直接将钱打给你。但是你不知道,也不用关注网贷平台的钱从哪里来。网贷平台内部他们可能从哪一个财主哪里融的钱。对你而言网贷平台和他们的金主是一起的。

同样通过上面我们例子可以看到,此时的代理服务器和后面的目标主机是一个系统的(百度公司、网贷平台)。他们是对外提供服务的,所以称为反向代理,代理的是后的人。

技术分享图片

 

 

 总结:正向代理隐藏真实客户端,反向代理隐藏真实服务端

代理主要有以下几种作用:

缓存(可以是公开的也可以是私有的,像浏览器的缓存)
过滤(像反病毒扫描,家长控制...)
负载均衡(让多个服务器服务不同的请求)
认证(对不同资源进行权限管理)
日志记录(允许存储历史信息)

 

 

 

 

 

 

 

 

 

 

 

 

 

原文:https://www.cnblogs.com/Gaimo/p/11926588.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!