Python爬虫(第三周)

目录

一、User-Agent的扩展

二、url携带参数

三、url传参

第一种方式(直接在url里面携带参数):

第二种方式(发送请求时携带参数):

四、网易云音乐小案例

五、ffmpeg的使用

六、Post请求

七、Cookie的扩展

八、SSL认证

九、代理IP


一、User-Agent的扩展

当需求是在一秒钟内访问某一网站30次,即对网站发送30次请求时,如果我们使用的是同一个User-Agent(用户代理),网站极有可能识别出来我们的爬虫身份。

解决办法:发送30次请求,使用30个不同的User-Agent(用户代理)

                  1.手动构建User-Agent池,一个列表里面储存着很多User-Agent,使用时每次从中随机取一个

                   2.使用第三方库 fake-useragent

# 1.手动构建User-Agent池
user_agents = [
    'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60',
    'Opera/8.0 (Windows NT 5.1; U; en)',
    'Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50',
    'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50',
    'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0',
    'Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10',
    'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2 ',
    'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36',
    'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
    'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16',
    'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36',
    'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko',
    'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.11 TaoBrowser/2.0 Safari/536.11',
    'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.71 Safari/537.1 LBBROWSER',
    'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)',
    'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.84 Safari/535.11 SE 2.X MetaSr 1.0',
    'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SV1; QQDownload 732; .NET4.0C; .NET4.0E; SE 2.X MetaSr 1.0) ',
]

# 2.使用第三方库fake-useragent
from fake_useragent import FakeUserAgent

user_agent = FakeUserAgent().random
print(user_agent)   
# Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36

二、url携带参数

百度主页的url:https://www.baidu.com/

当我们进行关键词搜收后的url(以搜索关键词:中国为例):https://www.baidu.com/s?wd=%E4%B8%AD%E5%9B%BD&rsv_spt=1&rsv_iqid=0xde60aa8800150949&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_dl=tb&rsv_sug3=8&rsv_sug1=8&rsv_sug7=101&rsv_sug2=0&rsv_btype=i&prefixsug=%25E4%25B8%25AD%25E5%259B%25BD&rsp=4&inputT=1609&rsv_sug4=2189

问题:当我们手动输入关键字:中国时,关键字是怎么到达百度服务器的呢?

答:浏览器将关键词添加到url当中,通过url携带参数(路由之后?之后所有的内容就是参数)

word=%E4%B8%AD%E5%9B%BD&

ts=3565893&

t_kt=0&

ie=utf-8&

fm_kl=021394be2f&

rsv_iqid=3116880672&

rsv_t=1fd8Sv%252BUY77sx7lJm38fviXEYz0cyC8aQlH9vT6COtZGsuFp5uSc48KQJw&

sa=ib&

ms=1&

rsv_pq=3116880672&

rsv_sug4=3597&

ss=110&

tj=1&

inputT=2042&

sugid=12057338745496505047

通过观察,可以发现他们都是以键值对的方式存在,两个参数(两个键值对)之间用and &符号分开,我们只输入关键词:中国,为什么会有这么多参数呢?其实这些大部分都是虚假参数,这些类似障眼法的参数即使拿掉也没有关系

https://www.baidu.com/s?wd=%E4%B8%AD%E5%9B%BD&rsv_spt=1&rsv_iqid=0xde60aa8800150949&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_dl=tb&rsv_sug3=8&rsv_sug1=8&rsv_sug7=101&rsv_sug2=0&rsv_btype=i&prefixsug=%25E4%25B8%25AD%25E5%259B%25BD&rsp=4&inputT=1609&rsv_sug4=2189

https://www.baidu.com/s?wd=中国&rsv_spt=1&rsv_iqid=0xde60aa8800150949&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_dl=tb&rsv_sug3=8&rsv_sug1=8&rsv_sug7=101&rsv_sug2=0&rsv_btype=i&prefixsug=%25E4%25B8%25AD%25E5%259B%25BD&rsp=4&inputT=1609&rsv_sug4=2189

我们在浏览器的地址栏和浏览器的抓包工具中对于同一个网页,他们url中的 wd 的内容却不一样

wd=%E4%B8%AD%E5%9B%BD

wd=中国

虽然 wd 的内容不一样,但却是同一个网页没有区别,这是因为在在我们发送请求时,中国两个字变成了%E4%B8%AD%E5%9B%BD

我们通常叫 中国 这类 为明文,%E4%B8%AD%E5%9B%BD我们看不懂的这类为密文(即为一种加密操作)

我们在python中如何实现这种加密和解密呢?(了解即可)

from urllib.parse import quote, unquote

# 先定义个明文数据
data_1 = '中国'  # 通过url编码,会变成一个怎样的密文?
# 明文转密文
data_2 = quote(data_1)
print(data_2)  # %E4%B8%AD%E5%9B%BD 通过对比和网站中中国的密文一样
# 密文转明文
data_3 = unquote(data_2)
print(data_3)  # 中国

三、url传参

第一种方式(直接在url里面携带参数):

# 导入发送网络请求的requests
import requests
from fake_useragent import FakeUserAgent

if __name__ == '__main__':
    # 确认关键词
    kw_ = input('请输入要搜索的关键词:')

    # 1.确认目标的url(前面分析了起作用的只有wd参数,其他参数都没有用)
    url_ = f'https://www.baidu.com/s?wd={kw_}&rsv_spt=1&rsv_iqid=0xde60aa8800150949&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_dl=tb&rsv_sug3=8&rsv_sug1=8&rsv_sug7=101&rsv_sug2=0&rsv_btype=i&prefixsug=%25E4%25B8%25AD%25E5%259B%25BD&rsp=4&inputT=1609&rsv_sug4=2189'

    # 构造用户代理User-Agent
    headers_ = {
        'User-Agent': FakeUserAgent().random
    }

    # 2.发送网络请求,获取响应对象
    response_ = requests.get(url_, headers=headers_)
    data_ = response_.content

    # 3.保存在本地
    with open('关键词1.html', 'wb') as f:
        f.write(data_)

第二种方式(发送请求时携带参数):

# 导入发送网络请求的requests
import requests
from fake_useragent import FakeUserAgent

if __name__ == '__main__':
    # 确认关键词
    kw_ = input('请输入要搜索的关键词:')

    # 1.确认目标的url(前面分析了起作用的只有wd参数,其他参数都没有用,第二种方法是在发送请求时加入关键字,所以把url中的wd参数删除掉)
    url_ = 'https://www.baidu.com/s?&rsv_spt=1&rsv_iqid=0xde60aa8800150949&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_dl=tb&rsv_sug3=8&rsv_sug1=8&rsv_sug7=101&rsv_sug2=0&rsv_btype=i&prefixsug=%25E4%25B8%25AD%25E5%259B%25BD&rsp=4&inputT=1609&rsv_sug4=2189'

    # 构造用户代理User-Agent
    headers_ = {
        'User-Agent': FakeUserAgent().random
    }

    # 在发送请求时为url添加参数,先构建关键字的键值对
    params_ = {'wd': kw_}

    # 2.发送网络请求,获取响应对象
    response_ = requests.get(url_, headers=headers_, params=params_)
    data_ = response_.content

    # 3.保存在本地
    with open('关键词2.html', 'wb') as f:
        f.write(data_)

四、网易云音乐小案例

音频:在浏览器中打开网易云音乐,找到自己喜欢的音乐(不能vip的音乐),鼠标右键点击检查,然后找到clear按钮点击清空数据包,点击播放,在network中找到对应的数据包。

音频的数据包一般在media中,但也有特殊情况。如果不在media中我们根据size的大小来判断是否为音频的数据包

检查自己找到的数据包是否正确:双击数据包的name,如果跳转到播放页面即为正确的音频文件的数据包

在找到正确的数据包后即可获得正确的url,此时我们就可以通过python对音频文件进行下载

# 导入发送网络请求的requests
import requests
from fake_useragent import FakeUserAgent

if __name__ == '__main__':
    # 1.确认目标的url
    url_ = 'https://m701.music.126.net/20210630211225/ce4b7f374598a629aa4dee55c19fcc5b/jdyyaac/obj/w5rDlsOJwrLDjj7CmsOj/9568880860/458f/d4f3/a66b/d40708839c04bf828333511e42e8fdbe.m4a'
    # 构造用户代理User-Agent
    headers_ = {
        'User-Agent': FakeUserAgent().random
    }

    # 2.发送网络请求,获取响应对象(因为音频为字节型数据,所以我们用content)
    response_ = requests.get(url_, headers=headers_)
    media_data = response_.content

    # 3.保存在本地
    with open('自我乍现.mp3', 'wb') as f:
        f.write(media_data)

视频:在浏览器中打开网易云音乐,找到自己喜欢的mv,鼠标右键点击检查,选择network,然后点击播放,在network中找到对应的数据包。

视频的数据包一般也在media中,但也有特殊情况。如果不在media中我们根据size的大小来判断是否为视频的数据包

检查自己找到的数据包是否正确:双击数据包的name,如果跳转到播放页面即为正确的视频文件的数据包

在找到正确的数据包后即可获得正确的url,此时我们就可以通过python对视频文件进行下载

# 导入发送网络请求的requests
import requests
from fake_useragent import FakeUserAgent

if __name__ == '__main__':
    # 1.确认目标的url
    url_ = 'https://vodkgeyttp9c.vod.126.net/cloudmusic/wJmKz8at_3552079912_hd.mp4?ts=1625062148&rid=47115DC667964F5C42BDE925D7219E80&rl=3&rs=gFAHHwFshGwxqOimUbUVWFTZUxUaAOka&sign=9e9367bcf08bd4555b3a6f3bee11d15b&ext=NnR5gMvHcZNcbCz592mDGR%252FsB9I27u7YCHC6INEq1zd2cXGX83DoffU4tC0T3SjX5hlTXZ8JzFfOIzpLOqFuM2pSGjQN76XXCVGPljB5HlsbZQuctrdE7J7NaG8g5GloNWUa1N3kcBHMFOi0v95X%252FNICdN16saSM42N9hcFcqndEtWiAI0os4UjHd6oM7r8NHMDIr8j7e6hlh0Rp3Jbfr3zEzgIweM3ipTiPiVXJLDoB9kGlyH40uyB9JC8lQQ4SDK40lXbx6mZEXd%252BJNix37TToSJLMeUk9bhmdfx7Q76QfepYCCMLuPU%252BWnevIPBUb0u75wMajucEEZ%252BJOBhZexGNT2YDmZCLI%252F4HWYYPhilihL9I8%252B%252Fvm%252BcDWhr445cljUGfLHjDA6YuvRfCmHM5GnM9jnEYq%252FX3TLDSkEbYhLYrdwerPeQ3hrevFlg%252BTIWlTntk7bbMF2j44EVvBTDk%252BFjaIVf%252Bnb96pd7rda0OekNYGQ1NZ78PVPbCXVeSkERzTknhIJSdhZfgjNOibNXe3Y1x94KDp957x3qjqYiH0TYM%253D'
    # 构造用户代理User-Agent
    headers_ = {
        'User-Agent': FakeUserAgent().random
    }

    # 2.发送网络请求,获取响应对象(因为视频为字节型数据,所以我们用content)
    response_ = requests.get(url_, headers=headers_)
    media_data = response_.content

    # 3.保存在本地
    with open('自我乍现.mp4', 'wb') as f:
        f.write(media_data)

五、ffmpeg的使用

上面提到我们要下载的音乐不能是vip才能下载的音乐,那么就没有办法下载到这首歌了吗?

在这我们用一个另辟蹊径的办法:有部分vip音乐是有mv的,而他们的mv通常是普通用户也可以看的,所以我们可以通过提取mv中的音频达到下载vip音乐的目的

实现方法:1.保存视频文件时,将后缀改为MP3(缺点:和mp4文件一样大)

                  2.使用ffmpeg提取音频(只支持抽离m4a音频格式,比mp3品质高)

此处我们重点介绍ffmpeg

ffmpeg -i 'xxx.mp4' -vn -y -acodec copy 'xxx.m4a'
# 导入发送网络请求的requests
import requests
from fake_useragent import FakeUserAgent
import os

if __name__ == '__main__':
    # 1.确认目标的url
    url_ = 'https://vodkgeyttp9c.vod.126.net/cloudmusic/AwGNgqeW_3531985312_hd.mp4?ts=1625064086&rid=47115DC667964F5C42BDE925D7219E80&rl=3&rs=bddUuGkKcYpPWrRkhiAASBFLjfomYbkX&sign=e049043991b442f0d356b8771ad7777c&ext=NnR5gMvHcZNcbCz592mDGZPybAa0NHJd4Dptbry7LRd2ZLECWfh7t3JkOxgr9p8UMST0DmFiJNFipj%252BcOuTr3GzDIwgJ0hDMDDCKcPwcEv%252Bgu4y5Pl1QYtyNhvBKoPJuMlY5redhDkwDNGhZJYp3qq5PrYwFjNhe8b2Wxxo5s3i7jU7nFSe9TS6tQV1blKk76SkOxJtZdkgzTEwW3pn5ddvKXdzgunAqkJnZe0upAJtCPZvZbyMggxoXp7DmXtaytMaF7YKHIXALGZDrgT5FKoD9ry7CYLhyEZmbY0sl4JOLGQfxhNQx2Lw02XuTYIOTuqWMuWFALT8mH8805PLxDrhi4jpU%252BA6FjBcbLgue%252FVDLQosZs1G1s09%252BuyE4Ly4ITg4jbBqcexLPJIc%252B96GiC2r%252FNDzv8ELnZcLOJ%252FtPdT5swGSnyZBz6ciRUSTjH46jSulYPecUjfxu14TRcdpUgdUaQXAZq9eH3cIzm5VZbLEnCQJeoVu7BF54AFOX86tUA4yBB2zVkfqRKM9r78nFqw%253D%253D'
    # 构造用户代理User-Agent
    headers_ = {
        'User-Agent': FakeUserAgent().random
    }

    # 2.发送网络请求,获取响应对象(因为视频为字节型数据,所以我们用content)
    response_ = requests.get(url_, headers=headers_)
    media_data = response_.content

    # 3.保存(视频)在本地
    with open('会不会.mp4', 'wb') as f:
        f.write(media_data)

    # 4.提取音频
    os.system('ffmpeg -i "会不会.mp4" -vn -y -acodec copy "会不会.m4a"')

    # 5.删除视频
    # os.remove('会不会.mp4')

六、Post请求

我们在平常的爬虫中,get请求用的多,post请求用的少

区别:get请求是直接向服务器发送请求,获取响应数据;post请求时客户端先给服务端一些数据,然后再获取响应(一般:登录操作都是post请求,因为要给服务端提供账号以及密码,提交完账号密码之后,才能获取到响应的响应)

虽然get请求可以在url中携带信息,但不安全而且能携带的数据量小

post请求可以在form表单中携带大量的数据,而且安全

当我们在一个网站登陆,进入登陆后的网站时,我们用此时的url在浏览器和使用python的get请求进行访问会出现不同的结果。我们使用python的get请求进行访问会得到登陆界面,而使用浏览器访问会进入登陆后的界面。这是因为浏览器会自动保存并携带cookie,cookie里面会有登录信息,这样就会自动登录,而我们在python代码中没有加入cookie,所以没有登陆信息,就会进入登陆界面。

如果想要获取登陆后的页面,应该怎么做?

1.利用python代码,发送post请求模拟登陆(用的比较少)

寻找登陆的url极其困难,此处以人人网为例

import requests
from fake_useragent import FakeUserAgent

if __name__ == '__main__':
    # 1.确认目标的url
    url_ = 'http://www.renren.com/PLogin.do'

    # 用户代理
    headers_ = {
        'User-Agent': FakeUserAgent().random
    }

    # post请求携带数据,form表单
    data_ = {
        'email': 'xxxxxxx',  # 账号
        'password': 'xxxxxxx'  # 密码
    }

    # 2.发送post请求
    response_ = requests.post(url_, headers=headers_, data=data_)
    content_ = response_.content

    # 3.保存
    with open('renren.html','wb') as f:
        f.write(content_)

2.拿到登陆后的Cookie,发送get请求(用的比较多)

import requests
from fake_useragent import FakeUserAgent

if __name__ == '__main__':
    # 1.确认目标的url(登陆后的url)
    url_ = 'xxxxxxxx'

    # 用户代理
    headers_ = {
        'User-Agent': FakeUserAgent().random,
        'Cookie': 'xxxxxx'  # 在network中主页的信息中找
    }

    # 2.发送get请求
    response_ = requests.get(url_, headers=headers_)
    content_ = response_.content

    # 3.保存
    with open('renren.html', 'wb') as f:
        f.write(content_)

七、Cookie的扩展

Cookie记录了客户端和服务端的交互记录,最主要的是有登录信息的记录,可以更好的模拟正常用户

我们使用的不同的User-Agent,但却使用携带有相同登录信息的Cookie肯定是不行的,此时就需要一个Cookie池

Cookie池:特别是记录了登陆信息的Cookie,每一个Cookie就代表了一个账号

                  1.买账号

                  2.注册不同的账号

当我们每次请求的User-Agent和Cookie都不相同的时候,服务端可能会发现这么多不同的用户的ip地址却相同,也会采取一定的反爬手段,所以我们还需要代理ip池

代理IP池:买

八、SSL认证

安全证书错误:您的连接不是私密链接(SSL证书缺失)

浏览器:下载安全证书即可

Python:会碰见SSL ERRO 即碰到了安全证书的问题 解决办法:绕过安全证书

import requests
from fake_useragent import FakeUserAgent

if __name__ == '__main__':
    # 1.确认目标的url(登陆后的url)
    url_ = 'xxxxxxxx'

    # 用户代理
    headers_ = {
        'User-Agent': FakeUserAgent().random,
        'Cookie': 'xxxxxx'  # 在network中主页的信息中找
    }

    # 2.发送get请求
    response_ = requests.get(url_, headers=headers_, verify=False)
    content_ = response_.content

    # 3.保存
    with open('renren.html', 'wb') as f:
        f.write(content_)

在发送get请求时加上:verify = False 的参数即可

九、代理IP

IP地址:精确的定位

IP地址:1.家里通网,有了一个路由器,有了一个IP,即公网IP

              2.电脑插上路由器的网线,电脑也有了自己的个人IP

代理IP:正向代理,即我们找了个中间商(代理IP)去找服务器,即使查出来我们是爬虫身份,也只会封禁中间商(代理IP)

Ngix:反向代理,一个服务端承受量可能有限,不能承受过多的用户访问,Ngix为了负载均衡,起路由分发的作用。相当于开了饭馆开了连锁店,去哪家店吃的都是一样的东西。

代理IP又分为透明代理(服务器知道我们使用了代理IP,并且知道我们的真实IP),匿名代理(服务器能够检测到我们使用了代理IP,但不知道我们真实的IP),高匿代理(服务器既不能检测出我们使用了代理IP,也无法知道我们的真实IP)

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不懂编程的大学生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值