爬虫(一)基础介绍

1. 爬虫简介

网络爬虫也叫做网络机器人,可以代替人们自动地在互联网中进行数据信息的采集与整理。它是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本,可以自动采集所有其能够访问到的页面内容,以获取相关数据。

爬虫的使用,能够在一秒内访问几十甚至几百次服务器,这种速度根本不是人所能达到的,因而也就给服务器加大了负担,如果持续这种访问量,甚至可能导致服务器崩溃,所以,各个网站对爬虫的访问都是有一些限制的和要求的。

1.1 robots协议

在要求方面,各个网站提供了robots协议,里面规定了该网站中哪些部分能够进行爬虫访问,哪些部分不能进行爬虫访问,这也称为君子协议,不过好像大部分都是小人,不怎么想遵守,如果想要查看一个网站的robots协议,只需要在网站网址的后面加上 robots.txt 即可,比如想要查看CSDN的robots协议,只需要在CSDN的网址 https://www.csdn.net/ 加上 robots.txt ,即输入网址 https://www.csdn.net/robots.txt 就可以看到下面的内容,意思是进禁止所有人访问该网站部分内容,还玩傲娇。
在这里插入图片描述

1.2 反爬手段

在限制方面,各大网站手段也是层出不穷,以前我不知道搞那些弱智的验证码有什么用,现在学了爬虫知道了,确实难受了一段时间,不过该行还是得行。反爬手段主要有以下几种:

  1. User Agent
    这种方法破解很简单,只需要将网页的 User Agent 复制了放入header即可。
  2. 代理IP
    该方法里网站设置了一些人类行为的阈值,只要高于这个行为网站就会将其视作爬虫,并封掉IP,禁止该IP访问。比如一秒内访问网页20次以上视作爬虫,这应该不过分吧。一般遇到这种情况,我们都会配置一个代理IP,使用代理IP来进行访问。
  3. 验证码访问
    这玩意经常遇到。
  4. 动态加载网页
    网站访问的是JS数据,不是网站的真实数据,可以使用selenium驱动浏览器进行请求。
  5. 数据加密
    这是最恶心的,将数据在JS代码里面加密,然后使用加密的数据发送请求,这种只有在JS代码里面找到加密规则,漫篇的打包后的JS代码,头都给看没。

1.3 请求组成

用户向服务器发送信息称之为请求,服务器向用户发送信息称之为响应。请求一般由请求方法、请求网址、请求头、请求体组成。

  1. 请求方法
    常见的请求方法如下:
    GET:请求页面,数据包含在URL里面
    POST:大多用于提交表单或者上传文件,数据包含在请求体中
    HEAD:类似GET请求,不过响应报文没有具体的内容,用于获取报头
    PUT:用客户端传送的数据取代指定的内容
    DELETE:请求服务器删除指定的页面
    CONNECT:把服务器当作跳板,让服务器代替客户端访问其他网页
    OPTIONS:允许客户端查看服务器的性能
    TRACE:回显服务器收到的请求,主要用于测试或者诊断
    不过我们见到和使用的大多数都是GET和POST请求

  2. 请求网址
    请求的网址即URL

  3. 请求头
    请求头,一般是传送服务器需要的一些附加信息,其中比较重要的就是User-Agent,Referer,Cookie等,常用的请求有说明如下

    Accept: 请求报头域,用于指定客户端可接受哪些类型的信息
    Accept-Language: 指定客户端可接受的语言类型
    Accept-Encoding: 指定客户端可接受的编码
    Host:用于指定资源主机的IP和端口号,其内容为请求URL的原始服务器或网关的位置
    Cookie:网站为了辨别用户进行会话跟踪而存储在用户本地的数据,它的主要功能是维持当前访问会话。
    Referer: 用来标识这个请求是从哪个页面发过来的,服务器可以拿到这一信息并做相应的处理,如做资源统计,防盗链接处理等。
    User-Agent: 可以是服务器识别客户端使用的操作系统及版本,浏览器及版本信息等。所以在做爬虫时要加上此信息,可以伪装浏览器;不加的话很容易被识别为爬虫。
    Conten-Type:互联网媒体类型,用来表示具体请求中媒体类型信息;如text/html代表HTML格式,image/gif代表GIF图片,application/json代表JSON类型

  4. 请求体
    请求体一般POST请求的时候才会有,因为GET请求的信息都在URL里。

1.4 响应组成

  1. 响应状态码
    状态码能够最基本的判定服务器对请求的响应情况,比如200就是请求成功,301就是重定向,404就是请求资源不存在,500就是服务器错误等,常见的一些如下:

    200:请求成功,服务器已成功处理请求。
    301: 重定向,请求的网页已经移动到新位置
    400: 请求错误401: 未授权,请求没有进行身份验证或者验证未通过
    403: 禁止访问404:未找到,请求资源不存在500:服务器错误
    503: 服务器无法使用

  2. 响应头
    响应头包含了服务器对请求的一些应答信息,如Server,Content-Type,Set-cookie等信息。

    content-type: 返回数据的类型
    sever:服务器名称,版本等信息
    set-cookie: 会话cookie,下次请求需要带上。

  3. 响应体
    响应信息中最重要的当属响应体了,因为我们想要获取的信息基本都在里面。python的request库也有对应的方法了提取相关信息,即 r.text

1.5 POST 请求与 GET 请求

POST请求和GET请求都是请求的方式,其区别如下:

  1. GET 请求,请求的数据会附加在 URL 之后,以?分割 URL 和传输数据,多个参数用&连接。POST 请求:POST 请求会把请求的数据放置在 HTTP 请求包的包体中。因此, GET 请求的数据会暴露在地址栏中,而 POST 请求则不会。
  2. 传输数据的大小对于 GET 请求方式提交的数据最多只能有 1024 字节,而 POST 请求没有限制。
  3. 安全性问题使用 GET 请求的时候,参数会显示在地址栏上,而 POST 请求不会。所以,如果这些数据是非敏感数据,那么使用 GET;如果用户输入的数据包含敏感数据,那么还是使用 POST 为好。

2. requests库

爬虫中很重要的一个库就是requests库,该库能够完全代替Python自带的urllib库,且使用起来更加简单高效。

2.1 GET请求

GET请求我们可以拿百度来进行尝试。

从网址搜索后百度的网址可以看出来,我们的搜索信息都在网址后面,使用的是 wd=关键词 的形式,比如下面我搜索requests后,百度的网页显示如下:

在这里插入图片描述
这里的 wd 明显与我们搜索的关键词一致,因此,我们只需要拼接后即可进行搜索。

为了防止其进行反爬,我们需要模拟用户请求,即将网站请求头的一些信息加入到我们的requests请求中,网站的请求头信息可以按F12在Network中筛选Fetch/XHR找到。
在这里插入图片描述
当然,这里面并不是每个请求头都有用,起最大作用的是 user-agent 以及 Cookie 请求头。

代码如下:

import requests

# 在使用requests库时,可以不用在后面加?,其会自动添加
url = 'https://www.baidu.com/s'
data = {
    'wd': '背景'
}
headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36',
    'Cookie': 'ORIGIN=2; ISSW=1; ISSW=1; BIDUPSID=F58D6799C8D928D5A89BE0274671EFA6; BD_UPN=12314753; BAIDUID=86EC4A79A69BC30551F1FD13B3AE7BA2:FG=1; PSTM=1662961767; BDUSS=JUbDcySUhQfjMtelJzYzd5cX5Kby1vfmFCMnFZWTBCTU10cnJ2SVBLbzJTRTlqRVFBQUFBJCQAAAAAAAAAAAEAAABcBQRhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADa7J2M2uydjN3; BDUSS_BFESS=JUbDcySUhQfjMtelJzYzd5cX5Kby1vfmFCMnFZWTBCTU10cnJ2SVBLbzJTRTlqRVFBQUFBJCQAAAAAAAAAAAEAAABcBQRhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADa7J2M2uydjN3; BDORZ=FFFB88E999055A3F8A630C64834BD6D0; H_PS_PSSID=26350; BAIDUID_BFESS=86EC4A79A69BC30551F1FD13B3AE7BA2:FG=1; delPer=0; BD_CK_SAM=1; PSINO=1; BA_HECTOR=852gak0l80a4a10h848k817d1hr74qv1i; ZFY=jgTOVcYL:Bdg0DHAbUhXQBWwwekSdsO0e3M8I:AuGvUec:C; B64_BOT=1; channel=baidusearch; baikeVisitId=31de3916-22bc-4816-a9ab-4ebe4d94b9b2; COOKIE_SESSION=321_0_2_3_12_1_1_0_2_1_18_0_3221_0_0_0_1672670956_0_1672713052|9#0_1_1671682412|1; H_PS_645EC=5e1ejfIQh/o7iHoCJqcOElbwpqojGL7pDiZ4mELA5If6tWQt/KbIX56pKTgD5GbedAlsG2DnInR7; WWW_ST=1672713491580'
}
response = requests.get(url, params=data, headers=headers)
print(response.text)

2.2 POST请求

这里我们寻找一个post请求的网页,百度翻译来进行讲解。

百度翻译肯定有一个请求是向服务器请求翻译的,我们只需要将其找出来,然后吧URL记录下来即可进行爬取。
在这里插入图片描述
在这里插入图片描述
通过我们一个单词一个单词的输入,我们可以发现,百度翻译的sug网页传递的就是我们的翻译请求的单词。然后复制下来该网页的Cookie值以及user-agent值到请求头,代码如下:

import requests
import json

url = 'https://fanyi.baidu.com/sug'

data = {
    'kw': 'what'
}

headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36',
    'Cookie': 'BIDUPSID=F58D6799C8D928D5A89BE0274671EFA6; BAIDUID=86EC4A79A69BC30551F1FD13B3AE7BA2:FG=1; PSTM=1662961767; APPGUIDE_10_0_2=1; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; BDUSS=JUbDcySUhQfjMtelJzYzd5cX5Kby1vfmFCMnFZWTBCTU10cnJ2SVBLbzJTRTlqRVFBQUFBJCQAAAAAAAAAAAEAAABcBQRhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADa7J2M2uydjN3; BDUSS_BFESS=JUbDcySUhQfjMtelJzYzd5cX5Kby1vfmFCMnFZWTBCTU10cnJ2SVBLbzJTRTlqRVFBQUFBJCQAAAAAAAAAAAEAAABcBQRhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADa7J2M2uydjN3; BDORZ=FFFB88E999055A3F8A630C64834BD6D0; H_PS_PSSID=26350; BAIDUID_BFESS=86EC4A79A69BC30551F1FD13B3AE7BA2:FG=1; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1672137088,1672154361,1672228903,1672714258; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1672714258; ab_sr=1.0.1_ZDgwZDczYmJmYmZlNGYxNGQ4MmE3M2Y5ODljNDhlNzI2ZWI4YmQ5MWZjOGZmZTUxYTcyMWUzOTIyMjc0Y2ZmMDM3MzRmMjVlMDgxYTRjOTBjYjVhNWU0YTgzNjA3OWZmMThiODNjYjUxM2RiM2EwZGVjZWIxNzllMzdhZDdkMGE4OTAxOTk1NTBmOGJhMjE2MzE0Nzc3ZjdkNzYyMGZiODVmYTAxMjE2ZDcyNTM4M2Y0ODkzMzI4NWM1NzMzZmRi'
}

response = requests.post(url, data=data, headers=headers)
# response.text 传递回来的编码有问题,需要用json将其转为‘utf-8’
obj = json.loads(response.text)
print(obj)

2.3 代理

代理需要一个能用的IP,这样如果你的IP被网站封了,那么使用代理后网站那么就会显示你使用的是代理后的IP进行请求,就不会拒绝访问。由于免费代理不太靠谱,我又不想花钱,这里我就给大家演示个模板吧。

import requests

# 在使用requests库时,可以不用在后面加?,其会自动添加
url = 'https://www.baidu.com/s'
data = {
    'wd': '背景'
}
headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36',
    'Cookie': 'ORIGIN=2; ISSW=1; ISSW=1; BIDUPSID=F58D6799C8D928D5A89BE0274671EFA6; BD_UPN=12314753; BAIDUID=86EC4A79A69BC30551F1FD13B3AE7BA2:FG=1; PSTM=1662961767; BDUSS=JUbDcySUhQfjMtelJzYzd5cX5Kby1vfmFCMnFZWTBCTU10cnJ2SVBLbzJTRTlqRVFBQUFBJCQAAAAAAAAAAAEAAABcBQRhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADa7J2M2uydjN3; BDUSS_BFESS=JUbDcySUhQfjMtelJzYzd5cX5Kby1vfmFCMnFZWTBCTU10cnJ2SVBLbzJTRTlqRVFBQUFBJCQAAAAAAAAAAAEAAABcBQRhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADa7J2M2uydjN3; BDORZ=FFFB88E999055A3F8A630C64834BD6D0; H_PS_PSSID=26350; BAIDUID_BFESS=86EC4A79A69BC30551F1FD13B3AE7BA2:FG=1; delPer=0; BD_CK_SAM=1; PSINO=1; BA_HECTOR=852gak0l80a4a10h848k817d1hr74qv1i; ZFY=jgTOVcYL:Bdg0DHAbUhXQBWwwekSdsO0e3M8I:AuGvUec:C; B64_BOT=1; channel=baidusearch; baikeVisitId=31de3916-22bc-4816-a9ab-4ebe4d94b9b2; COOKIE_SESSION=321_0_2_3_12_1_1_0_2_1_18_0_3221_0_0_0_1672670956_0_1672713052|9#0_1_1671682412|1; H_PS_645EC=5e1ejfIQh/o7iHoCJqcOElbwpqojGL7pDiZ4mELA5If6tWQt/KbIX56pKTgD5GbedAlsG2DnInR7; WWW_ST=1672713491580'
}
# 设置代理
proxy = {
    'http': '212.129.251.56:16896'
}
# 将代理放入请求
response = requests.get(url, params=data, headers=headers, proxies=proxy)
print(response.text)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值