爬虫第一天

爬虫是一个应用程序

是指某一个用于爬取数据的应用程序,爬取的目标可以是整个互联网  也可以是单独的某一个服务器

在CS结构中 爬虫属于client 客户端

爬虫的价值:互联网中最重要的就是数据,爬虫首要任务就是要通过网络去获取服务器的数据:来为自己创造价值

爬虫的流程

首先明确 爬虫是客户端 要爬的数据在服务器上存储,所以需要借助网络编程,底层的网络协议已经有现成的封装不需要自己写,数据传输已经解决,问题是对方给我的数据我能不能看懂,我的数据对方能否看懂

绝大多数网络传输都是采用的HTTP

HTTP 协议 超文本传输协议

1.明确要爬取得url地址

分析请求web页面(chrome)原生软件(抓包工具如Charles)

2.发送请求

第三方requests模块   高度封装了HTTP

内置的urllib模块

selenium是因为一些网站需要人机交互(点击拖拽等等操作)

针对移动app可以使用代理服务器,可以截获app端发送的请求信息,Chaeles(青花瓷)

3.接收响应

浏览器接受响应后会渲染页面进行展示 无法拿到数据

所以更多情况下使用浏览器来分析请求详情

requests和urllib都会直接返回响应体

selenium提供了find_element***的接口用于获取数据

4.解析数据

re

BeautifulSoup 封装了常用的正则表达式

移动端返回的/ajax返回的json数据  直接json.load

5.存储数据

mysql等关系型数据库

Mongodb redis 等菲关系型数据库  一般用在高并发爬虫中

接口测试工具 postman paw(mac可以自动生成请求代码)

Scrapy爬虫框架

爬取梨视频

爬取的流程

1.爬取首页中所有的视频的id

2.拼接详情地址并请求

3.通过re解析数据

4.将结果存储为json数据

分析请求头中有用的信息

1.user-agent用来识别客户端类型

2.refer 用来识别 用户从哪个页面过来的

3.Cookie 当页面需要验证用户身份时 使用

响应头:

location 当请求被重定向时 就会带有该字段 可以通过状态码30* 来识别重定向

发送post请求

requests 中

get请求 参数放在地址后或是使用params参数来制定一个字典

post请求:参数使用data参数来指定 是一个字典

如果是登录请求一般都需要带token

先发送请求获取token的值  token值一定都在一个form表单中

HTTP请求分析:

首先要明确的是:爬虫的核心原理就是模拟浏览器发送HTTP协议来获取服务器上的数据,那么要想服务器接收你的请求,则必须将自己的请求伪装的足够像,这就需要我们去分析浏览器是如何发送的HTTP请求

其次:HTTP协议是基于请求响应模型的,客户端发送请求到服务器,服务器接受请求,处理后返回数据,需要关注的重点在于请求数据,只有服务器任何合格合法的请求才会得到服务器的响应

利用chrome开发者工具来分析请求

chrome浏览器提供强大的开发者工具我们可以利用它来查看浏览器与服务器的整个通讯过程

请求流程分析

请求地址:浏览器发送的请求URL地址

请求方法:

get:中文需要URL编码,参数跟在地址后面

post:参数放在body中

请求头:cookie需要登陆成功才能访问的页面就需要传递cookie,否则不要要

user-agent,:用户代理,验证客户端的类型

referer,引用页面,判断是从那个页面点击过来的

请求体:只在post请求时需要关注,通常post请求参数都放在请求体中,例如登录的用户名和密码

响应头:

location:重定向后的目标地址,尽在状态码为3**时出现,需要考虑重定向时的方法,参数等.浏览器会自动重定向,requests模块也会

set-cookie:服务器返回的cookie信息,在访问一些隐私页面时需要带上cookie

响应体

服务器返回的数据,可能有以下几种类型

HTML格式的静态页面  需要解析获取的数据

json格式的结构化数据  直接就是纯粹的疏忽

二进制数据(图片视频等) 通过文件操作直接写入文件

requests模块的使用:

get请求:请求参数

1.参数拼接时中文需要URLEncode,可以使用urllib中的编码函数来完成

from urllib.parse import urlencode

import requests

params={"word":"美女"}必须以字典类型传入需要编码的数据,得到拼接后的参数字符串

res = urlencode(params,encoding="utf-8")

url = "https://www.baidu.com/s"

url = url+"?"+res  #拼接参数

response = erquests.get(url)

with open("test.html","wb") as f:

  f.write(response.content)

2.也可以直接将请求参数传给get的函数的param参数,get将会自动完成编码

import requests

params={"wd":"美女"}

url = "https://www.baidu.com/s"直接传params参数

response  =requests.get(url,params=params)

上述代码无法完成请求完成的数据,因为百度服务器有限制必须指定用户代理,user-agent为浏览器才行

添加请求头:

import requests

params={"wd":"美女"}

url="https://www.baidu.com/s"

headers = {"user-agent":"Mozilla/5.0...."}

response=request.get(url,params=params,heades=headers)

cookies

可以在headers中直接添加键值对也可以单独使用个体方法的cookies参数

url = "https://github.com/yangyuanhu"
headers = {
"User-Agent" : 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/71.0.3578.98 Mobile Safari/537.36',
"Cookie":"_octo=GH1.1.1155792533.1532919557; _ga=GA1.2.1847433334.1534242542;
has_recent_activity=1; user_session=Z5AQmC_Wv4wvM-_Nc3Bj0PQn6nITSonDcPkw4GZ1g0jFIqbe;
__Host-user_session_same_site=Z5AQmC_Wv4wvM-_Nc3Bj0PQn6nITSonDcPkw4GZ1g0jFIqbe;
logged_in=yes; dotcom_user=yangyuanhu; tz=Asia%2FShanghai; _gat=1;
_gh_sess=eERwWHk1NVBjOEhIRmxzckcrcWlpVCtUM2hWL0prNlIyNXdTdC9ab0FSZWR5MEZlYW5OVGNo
TEdJQUN0K0xkNXVmTEVpK2RRU1VZTUF6NkJHM1JMejNtaVhReXg2M3Vsb0JvcG8vNDNENjNBcXVvcFE4T
mp4SFhpQ3Z3S2ZZZEIwTGNkVW5BR01qVHlCNEFqTnZFcllhN3NwT1VJblZYWElLOGowN3ZaZVpZTFVHQlF
tZkh3K1hnclBWalB1Mk1XLS1wNjFjMlBxUHljU2paK2RXU3M5eDB3PT0%3D--8cdf657174d2acac7cc0459da667accc8a2d0f5e",
"Referer": "https://github.com/"
}
response = requests.get(url,headers=headers)
with open("test.html","wb") as f:
f.write(response.content)

使用cookies参数 注意需要拆分为单独的键值对

requests模块自动处理(session)cookies

POST请求

post请求不同之处仅在于参数提交通过post方法的data参数来指定:模拟登陆流程并爬取github私有页面

模拟登录流程并爬取github私有页面

```python
import requests
import re


user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/71.0.3578.98 Safari/537.36"
# 创建一个会话
session = requests.session()


# 1.请求登录页面
res = session.get("https://github.com/login",headers={
"Referer": "https://github.com/",
"User-Agent": user_agent
})
print(res.status_code)
token = re.search('name="authenticity_token" value="(.*?)"',res.text).group(1)
print(token)

# 2.发送登录请求,带上cookie,带上请求体,带上token
res2 = session.post("https://github.com/session",
headers = {
"Referer": "https://github.com/login",
"User-Agent": user_agent},
data={
"commit": "Sign in",
"utf8": "✓",
"authenticity_token": token,
"login": "oldboyedujerry",
"password": "123654asdAsd"},
allow_redirects = True)
print(res2.status_code)
# 访问个人主页
res3 = session.get("https://github.com/settings/profile",
headers={
"User-Agent": user_agent,
"Referer": "https://github.com/login"
})

print(res3.status_code)
with open("tt.html","wt") as f:
f.write(res3.text)
# 判断是否登录成功
print("oldboyedujerry" in res3.text)


```

注意通常登录时都会带token,需要现货区token才能进行post登录

## session的使用

使用会话来完成请求,会话会自动帮我们保存和提交cookie

```python
user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/71.0.3578.98 Safari/537.36"
# 创建一个会话
session = requests.session()


# 1.请求登录页面
res = session.get("https://github.com/login",headers={
"Referer": "https://github.com/",
"User-Agent": user_agent
})
print(res.status_code)
token = re.search('name="authenticity_token" value="(.*?)"',res.text).group(1)
print(token)

# 2.发送登录请求,带上cookie,带上请求体
res2 = session.post("https://github.com/session",
headers = {
"Referer": "https://github.com/login",
"User-Agent": user_agent},
data={
"commit": "Sign in",
"utf8": "✓",
"authenticity_token": token,
"login": "oldboyedujerry",
"password": "123654asdAsd"},
allow_redirects = False
)

print(res2.status_code)

# 访问个人主页
res3 = session.get("https://github.com/settings/profile",
headers={
"User-Agent": user_agent,
"Referer": "https://github.com/login"
})

print(res3.status_code)

with open("tt.html","wt") as f:
f.write(res3.text)
# 判断是否登录成功
print("oldboyedujerry" in res3.text)

requests模块为我们封装了获取cookie的方法:token需要手动获取

login_url= "http://github.com/login"

resp = requests.get(login_url)

cookie = resp.cookies.get_dict()

token = re.search("authenticity_token" value="(.*?) />",resp.text)

# 2.请求登录接口
login_url = "https://github.com/session"
resp2 = requests.post(login_url,
headers={
"Referer": "https://github.com/login",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36",
},
data={"commit": "Sign in",
"utf8": "✓",
"authenticity_token": token,
"login": "oldboyedujerry",
"password": "123654asdAsd",
"webauthn-support": "supported"},
cookies = cookie)

通过使用session方法(可以出去获取cookie的过程简便操作)

原文地址:https://www.cnblogs.com/suncunxu/p/10684856.html