Python 爬虫

什么是爬虫:

        爬虫 就是给网站发起请求,并从响应中提取需要的数据的自动化程序,在爬取数据的时候

  • 爬虫的原理

如果要获取网络上的数据,我们要给爬虫一个网址(程序中通常叫URL),爬虫发送一个HTTP请求给目标网页的服务器,服务器返回数据给客户端(也就是我们的爬虫),爬虫在进行数据解析、存保等一系列操作

  • 爬取数据的流程
        爬虫可以节省我们的时间,比如我要获取豆瓣电影 Top250 榜单,如果不用爬虫,我们要先在浏览器上 输入豆瓣电影的 URL ,客户端(浏览器)通过解析查到豆瓣电影网页的服务器的 IP 地址,然后与它建 立连接,浏览器再创造一个 HTTP 请求发送给豆瓣电影的服务器,服务器收到请求之后,把 Top250 榜单从数据库中提出,封装成一个 HTTP 响应,然后将响应结果返回给浏器,浏览器显示响应内容, 我们看到数据。 爬虫也是根据这个流程,只不过改成了代码形式。
第一步:发起请求,获取响应结果
     1.通过HTTP库,对目标站点进行请求,等同于模拟打开浏览器,输入网址,获得数据的整个过程。
     2.常用库: urllibx  ,  urllib3x  ,  requests,这些是常用的库文件
     3.服务器会返回请求的内容,一般为:HTML文件、二进制文件(视频,音频、图片) 、文档、 json字符串 等
第二步:解析内容
        寻找自己需要的信息,就是利用正则表达式或者其他库提取目标信息
        常用库:re、beautifulsoup4 、这两个库可以实现从拿到的信息中提出所关注的信息
第三步:保存数据
将解析得到的数据持久化到文件或者数据库中
  • HTTP请求报文
        请求报文构成
                HTTP请求 是产生于客户端的
                HTTP请求格式包括三个部分
第一部分:请求行:
  • 在请求行,树妖包括三个部分
  • 请求方法,URL、协议版本 

第二部分: 请求头:

  • 在请求头中,主要是存向服务器端发请求的时候键值对

第三部分: 请求体:

        请求体是发送给服务器请求时候,所携带的数据,比如你的账号密码

 

 

HTTP请求举例:
  
  •  第一行是:请求行
  • 第二 ~ 十一行是:请求头
  • 第十二行是: 空白行
  • 第十三行是: 请求体

请求行一定是http请求的第一行,包括下面几个部分

第一部分:请求方法
  • GET:查询
  • POST:添加
  • DELETE:删除
  • PUT:修改
  • 注意:不区分大小写
第二部分:URL
第三部分:协议
  • HTTP1.1
  • HTTP1.0
  • HTTP0.9
另外,请注意
  • 只有POST和PUT方法有请求体,原因是无论是添加,还是修改,需要将对应的数据发送到服务器 端,这样服务器端才能进行对应的修改操作
  • 而GET和DELET方法是没有请求体的
  • 请求头    
对于请求头来说,我只要记住一个键值对就可以了,就是Content-Type这个,其他的,只要知道请求头里都是键值对就够了
Content-Type
1. Content-Type:是用于描述请求体中的数据是什么类型的数据
2. 必须严格区分大小写
3. 对于GET 和 DELETE请求,不需要这个,因为这两个方法里没有请求体
4. 只有当请求方法是POST和PUT的时候,这个参数才有用
Content-Type 请求体数据类型
1. text/html 表示HTML格式
2. text/plain 表示纯文本格式
3. text/jpeg 表示jpeg图片格式
4. application/json:表示JSON格式数据
5. application/x-www-form-urlencoded 表示默认的提交数据格式
6. multipart/form-data 表示在表单中进行文件上传时使用的格式
  • 请求体
请求体是位于空行之下的内容
有的协议没有请求体,比如get delete
请求的体的数据类型,受请求头的中的content-type的值影响
可以尝试用开发者工具抓包查看不同请求下,http请求报文的格式,包括
正常访问页面
登录页面
结果中就会发现,有的数据是有请全体的,但是有的是没有的
  • HTTP响应报文
  • 响应报文的构成
在http响应这里,我主要学习两个东西
  • http响应状态码
  • http的响应体
httpd响应,一定是服务器端产生的
只有在服务器端收到客户端的请求以后,服务器端才会产生http响应报文
http的响应是也包括三个部分的
第一部分:响应行,也称之为状态行,包括了 协议版本、状态码、状态码描述
第二部分:响应头,我们只需要知道格式是k-v格式,但是我们不需要记任何具体的内容
空行
第四部分:响应体,响应体是服务器端返回给客户端的数据

 

注意:
GET和DELETE的请求报文中,是没有请求体的
但是对于响应报文来说,所有的响应报文,都是有响应体的。**
案例:找出响应行、响应头、响应体
HTTP/1.1 200 OK
Data: Fri, 22 Oct 2022 06:07:02 GMT
Content-Type: text/htlm; charset=UTF-8
<html>
<head><head>
<body>....</body>
</html>
Content-Type的作用和请求头中的作用是一样的,都是用于描述体中的内容格式
  • 相应行
位置是响应数据包的第一行
作用是描述服务器的处理结果
内容构成:
  • 协议版本号
  • 状态码
  • 消息短语
状态码有三个数字构成
1xx:提示信息
2xx:成功
3xx:重定向
4xx:客户的错误
5xx:服务器端错误

 

  • 响应头
位于响应行之下,空行之上的部分
数据的组织格式都是K-V对
  • 响应体
位于空行之下
几乎所有的响应报文,都有相应体
  • 不管是查询,还是删除,虽然请求报文中没有请求体,但是无论这个数据有没有,都必须给个回 应,所以说,一般都是有响应体的。
  • 只有极端的情况,才会没有响应体,这个我们一般系接触不到

发送请求的方法

urllib 发请求
自带模块
在发送请求的时候,可以urllib模块
方法名:request.urlopen()
案例:向百度发送请求
# coding = utf-8

import time
import sys
from urllib import request

# 需要注意协议类型
url = "http://www.baidu.com"
# 获取相应的对象
res = request.urlopen(url)

# 获取响应头
print(f"响应头是:{res.info}")

# 获取状态码
print(f"状态码是:{res.getcode()}")

# 获取主机地址
print(f"主机地址是:{res.geturl()}")

# 获取响应体中数据
# 获取返回的字节码格式内容
# 如如果返回的字节码内容多的话,会直接打印乱码
html_comtent = res.read()
# print(html_comtent)

# 对字节码内容进行解码
print(html_comtent.decode("utf-8"))

注意,这种爬取数据的方式,在很多网站是被禁止的
比如在爬取 大众点评的时候,就会失败,一种简单的应对方法就是在发送请求的时候,伪造一个浏 览器信息,比如
具体如下:
# coding = utf-8
import time
import sys
from urllib import request
# 需要注意协议类型
url = "http://www.baidu.com"
# 定义头信息
header = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
# 用Request发送请求
req = request.Request(url, headers=header)
# 获取相应的对象
res = request.urlopen(url)
# 获取响应头
print(f"响应头是:{res.info}")
# 获取状态码
print(f"状态码是:{res.getcode()}")
# 获取主机地址
print(f"主机地址是:{res.geturl()}")
# 获取返回的字节码格式内容
# 如如果返回的字节码内容多的话,会直接打印乱码
html_comtent = res.read()
# print(html_comtent)
# 对字节码内容进行解码
print(html_comtent.decode("utf-8"))

  • requests 发请求
  • request库简介
    这个request库,他的作用其实也就是发送http请求,需要有请求行、请求头、请求体
安装requests库
        方法1:pip安装
安装的命令
  • pip install requests -i https://pypi.douban.com/simple/
检查安装结果的
  • pip list
  • pip show 库名
方法2:pycharm中进行安装

 

 

request库语法
首先要知道,所谓的库,其实是一个简称,全称应该是函数库,就是这是一个仓库,在仓库里面放的 是一个一个的函数
因此,我们是使用库,其实是调用这个库的函数。这是原理。
Request库中的http请求语法格式

 

思考一下:上面写了,请求体有表单格式的,用data表示;也可以是json格式的,用json表示json格 式的请求体。问题:这两个参数能同时用码?

  • 肯定不可以
  • 请求体只能是一种数据格式
补充一点:关于字符串的引号的问题
在python中,表示字符串的时候,可以用双引号,也可以用单引号,都没问题。但是为了和其他的
编程语言兼容,因此建议用双引号
  • 入门的案例
import requests

# 定义目标url
dest_url = "https://www.baidu.com"

# 向url发送请求
rest = requests.get(dest_url)

# 获取状态码
print(rest.status_code)

# 获取响应体中的数据
print(rest.text)
可以将显示结果换行显示

 

  • 获取返回数据方法
  • 【都是从resp中获取指定数据的】
1. 获取 URL:resp.url
2. 获取 响应状态码:resp.status_code
3. 获取 Cookie:resp.cookies
4. 获取 响应头:resp.headers
5. 获取 响应体:
​​​​​​​
  • 文本格式:resp.text
  • json格式:resp.json()
  • 注意:不是所有的结果都能转换成json格式数据。如果是将不能转成为json格式的数据进行 了转换,那么就会报错,报错信息如下:JSONDecodeError,下面最后的一个案例,就会 报这个错
import requests

# 定义目标url地址
dest_url = "https://www.baidu.com"

# 向目标发送http请求
res = requests.get(url=dest_url)

# 输出结果信息
print(f"响应状态码:{res.status_code}")
print(f"请求的url:{res.url}")
print(f"获取Cookie:{res.cookies}")
print(f"获取编码类型:{res.encoding}")

# print(f"获取响应头:{res.headers}")
print(f"获取响应体:{res.text}")

需要注意的点
1. ISO-8859-1编码是单字节编码,向下兼容ASCII
        1. Content-type:text/html 就是表示了这个页面文件的格式是文本文件
        2. 如果在Content-type中使用了关键字 Charset=XXX,那么编码就是这个指定的;人工没有 指定的话,那么编码就用ISO-8859-1
        3. 如果在header中没有出现 Content-type 这个关键字的话,那么编码就是utf-8
现在的编码是8859-1,所以在显示中文的时候,一定有乱码,如下
import requests

# 定义目标url地址
dest_url = "https://www.baidu.com"

# 向目标发送http请求
res = requests.get(url=dest_url)

# 输出结果信息
print(f"响应状态码:{res.status_code}")
print(f"请求的url:{res.url}")
print(f"获取Cookie:{res.cookies}")
print(f"获取编码类型:{res.encoding}")

# print(f"获取响应头:{res.headers}")

# 将收到的内容编码,用utf-8进行编码,避免出现中文乱码
res.encoding = "utf-8"
print(f"获取响应体:{res.text}")

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值