urllib与requests爬虫简介

news2024/12/23 0:05:51

urllib与requests爬虫简介 – 潘登同学的爬虫笔记

文章目录

    • urllib与requests爬虫简介 -- 潘登同学的爬虫笔记
    • 第一个爬虫程序
  • urllib的基本使用
    • Request对象的使用
    • urllib发送get请求
      • 实战-喜马拉雅网站
    • urllib发送post请求
  • 动态页面获取数据
    • 请求 SSL证书验证
    • 伪装自己的爬虫-请求头
  • urllib的底层原理
    • 伪装自己的爬虫-设置代理
    • 爬虫cookie的使用
      • 代码登录-并保持登录状态
      • 爬虫保存与读取cookie
    • urllib的异常处理
  • requests模块
    • requests伪装爬虫
    • 设置超时时间
    • session自动保存cookies
    • ssl验证
    • 获取响应信息的方法

第一个爬虫程序

from urllib.request import urlopen
response = urlopen("http://www.baidu.com/")
print(response.read().decode())

urllib的基本使用

  • requset.urlopen(url,data,timeout):打开一个url,并返回一个response对象。
    • url:要打开的url地址。
    • data:如果是POST请求,则需要提供要发送的数据。
    • timeout:设置请求超时时间,单位为秒。
  • response.read():读取response的内容,返回bytes类型
  • response.getcode():返回 HTTP的响应码,成功返回200,4服务器页面出错,5服务器问题
  • response.geturl():返回实际请求的url地址
  • response.info():返回response的头部信息

Request对象的使用

使用urllib.request.urlopen发送请求时,可以将参数封装到一个Request对象中。

from urllib.request import urlopen
from urllib.request import Request
url = 'http://www.server.com/login'
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' 
headers = { 'User-Agent' : user_agent }  
request = Request(url, headers=headers)  
response = urlopen(request)  
page = response.read() 

运行结果和直接传递URL完全一样的,只不过中间多了一个request对象,推荐大家这么写,因为在构建请求时还需要加入好多内容,通过构建一个request,服务器响应请求得到应答,这样显得逻辑上清晰明确

在这里插入图片描述

urllib发送get请求

Get请求的参数都是在Url中体现的,如果有中文,需要转码,这时我们可使用

  • urllib.parse.urlencode() 转换键值对
  • urllib.parse. quote() 转换一个值
from urllib.request import urlopen,Request
from urllib.parse import quote
args =input('请输入要搜索的内容:')
ua = UserAgent()
url = f'https://www.baidu.com/s?wd=
{quote(args)}'

# 或者
# parms ={
#  'wd':args
#  }
#  url = f'http://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=baidu&{urlencode(parms)}'

headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.47'
}
req = Request(url,headers = headers)
resp = urlopen(req)
print(resp.read().decode())

实战-喜马拉雅网站

喜马拉雅网站音乐栏目 https://www.ximalaya.com/yinyue/

from urllib.request import urlopen,Request
from time import sleep

def spider_music(_type,page):
    for num in range(1, page+1):
        if num == 1:
            url = f'https://www.ximalaya.com/yinyue/{_type}'
        
        else:
            url = f'https://www.ximalaya.com/yinyue/{_type}/p{num}/'
        headers = {
            'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.47'
        }
        req = Request(url,headers = headers)
        resp = urlopen(req)
        html = resp.read().decode()
        # 解析html
        # 保存数据
        # 休息一会儿
        sleep(1)
        print(f'第{num}页数据爬取完成')

if __name__ == '__main__':
    spider_music('minyao',10)

urllib发送post请求

如何查看post请求的参数名称:可以随便发送一些数据,在网络中的login请求中,点击载荷,可以查看到参数名称。

from urllib.request import Request,urlopen
 from urllib.parse import urlencode
 url = 'https://www.kuaidaili.com/login/'
# 封装数据
data = {
    'next': '/login/?next=%2F',
    'login_type': '1',
    'username': '398707160@qq.com',
    'passwd': '111111111',
}

tru_data = urlencode(data).encode()
# 封装头信息
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36'}

# 封装Request对象
req = Request(url,data=tru_data,headers=headers)
resp = urlopen(req)
print(resp.read().decode())

动态页面获取数据

有时在访问了请求后,并不能获取想要的数据。很大的原因之一就是,当前的页面是动态的。目前网络的页面分为2大类:

  1. 静态页面:特征:访问有UI页面URL,可以直接获取数据
  2. 动态页面(AJAX):特征:访问有UI页面URL,不能获取数据。需要抓取新的请求获取数据

有些网页内容使用AJAX加载,而AJAX一般返回的是JSON,直接对AJAX地址进行post或get,就返回JSON数据了

情形:https://www.hupu.com/页面有新闻,不断向下拉可以加载更多新闻,但是不能直接获取数据,需要使用AJAX加载数据。

from urllib.request import urlopen,Request
import json

url = 'https://www.hupu.com/home/v1/news?page=2&pageSize=50'
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36'
}
req = Request(url,headers=headers)
resp = urlopen(req)
html = resp.read().decode()
print(html)
'''
静态
    访问地址栏里的数据就可以获取到想要的数据。 
动态
    访问地址栏里的数据就可以获取不到想要的数据。 
解决方案:抓包
    打开浏览器的开发者工具-network-xhr,找到可以获取到数据的url访问即可
'''

请求 SSL证书验证

现在随处可见 https 开头的网站,urllib可以为 HTTPS 请求验证SSL证书,就像web浏览器一样,如果网站的SSL证书是经过CA认证的,则能够正常访问

如果SSL证书验证不通过,或者操作系统不信任服务器的安全证书,比如浏览器在访问12306网站的时候,会警告用户证书不受信任。(据说 12306 网站证书是自己做的,没有通过CA认证)

import ssl
# 忽略SSL安全认证
context = ssl._create_unverified_context()
# 添加到context参数里
response = urlopen(request, context = context)

伪装自己的爬虫-请求头

  1. User-Agent:浏览器的标识,可以伪装成浏览器,让网站认为是浏览器访问。

有些网站不会同意程序直接用上面的方式进行访问,如果识别有问题,那么站点根本不会响应,所以为了完全模拟浏览器的工作,要使用faked-useragent库。

pip install fake-useragent
from fake_useragent import UserAgent
ua = UserAgent()
url =  'http://httpbin.org/get'

headers = {
    'User-Agent':ua.random
}
req = Request(url,headers=headers)
resp = urlopen(req)
print(resp.read().decode())

注意

  • fake-useragent 在创建对象时,可能创建不了,多部分原因为服务器访问不到的原因
  • 解决方案:拷贝 fake-useragent_version.json 的配置文件到用户目录C:\Users\Feel\AppData\Local\Temp

urllib的底层原理

当你获取一个URL你使用一个opener(一个urllib.OpenerDirector的实例)。在前面,我们都是使用的默认的opener,也就是urlopen。它是一个特殊的opener,可以理解成opener的一个特殊实例,传入的参数仅仅是url,data,timeout。

如果我们需要用到Cookie,只用这个opener是不能达到目的的,所以我们需要创建更一般的opener来实现对Cookie的设置

from urllib.request import Request,build_opener
from fake_useragent import UserAgent

url = 'http://httpbin.org/get'
headers = {
    'User-Agent':UserAgent().random
}
req = Request(url,headers=headers)
opener = build_opener()
resp = opener.open(req)
print(resp.read().decode())

handler能实现一些附加的功能,如要显示headers,可以用HTTPHandler。

from urllib.request import Request,build_opener,HTTPHandler
from fake_useragent import UserAgent

url = 'http://httpbin.org/get'
headers = {
    'User-Agent':UserAgent().random
}
req = Request(url,headers=headers)
opener = build_opener(HTTPHandler(debuglevel=1))
resp = opener.open(req)
print(resp.read().decode())

伪装自己的爬虫-设置代理

爬虫设置代理就是让别的服务器或电脑代替自己的服务器去获取数据

在这里插入图片描述

  • 透明代理:目标网站知道你使用了代理并且知道你的源IP地址,这种代理显然不符合我们这里使用代理的初衷
  • 匿名代理:匿名程度比较低,也就是网站知道你使用了代理,但是并不知道你的源IP地址
  • 高匿代理:这是最保险的方式,目标网站既不知道你使用的代理更不知道你的源IP
from urllib.request import Request,build_opener,ProxyHandler
from fake_useragent import UserAgent

# 设置访问地址
url = 'http://httpbin.org/get'
# 设置请求对象
req = Request(url)
# 构建可以使用代理的控制器
handler = ProxyHandler({'http': 'http://101.10.13.10:3128'})
# 构建opener
opener = build_opener(handler)
# 发送请求
resp = opener.open(req)
print(resp.read().decode())

爬虫cookie的使用

网络部分信息或APP的信息,若是想获取数据时,需要提前做一些操作,往往是需要登录,或者提前访问过某些页面才可以获取到!!

其实底层就是在网页里面增加了Cookie信息。cookie通常在请求头里设置,而urllib的Request对象可以设置headers信息。

  1. 登录获取cookie,点击检查,查看network,找到访问的url地址,找到cookie信息,复制到本地,保存到本地文件。
from urllib.request import Request,build_opener
from fake_useragent import UserAgent
 url ='https://www.kuaidaili.com/usercenter/overview'
 headers = {
 'User-Agent':UserAgent().chrome,
 'Cookie':'channelid=0; sid=1621786217815170; _ga=GA1.2.301996636.1621786363; _gid=GA1.2.699625050.1621786363; Hm_lvt_7ed65b1cc4b810e9fd37959c9bb51b31=1621 786363,1621823311; _gat=1; Hm_lpvt_7ed65b1cc4b810e9fd37959c9bb51b31=162 1823382; sessionid=48cc80a5da3a451c2fa3ce682d29fde7'
}
req = Request(url,headers= headers)
opener = build_opener()
resp = opener.open(req)
print(resp.read().decode())

代码登录-并保持登录状态

问题

  • 不想手动复制cookie,太繁琐了!

解决方案

  • 在再代码中执行登录操作,并保持Cookie不丢失
from urllib.request import Request,urlopen,HTTPCookieProcessor
from fake_useragent import UserAgent

url = 'https://www.kuaidaili.com/login/'
headers = {
    'User-Agent':UserAgent().chrome
}
# 发送请求,用于登录用户
data = {
    'next': '/',
    'login_type': '1',
    'username': '398707160@qq.com',
    'passwd': '111111111',
}
tru_data = urlencode(data).encode()
req = Request(url,data=tru_data,headers=headers)
handler = HTTPCookieProcessor()
opener = build_opener(handler)
resp = opener.open(req)
# 发送请求,获取数据
index_url = 'https://www.kuaidaili.com/usercenter/overview'
index_req = Request(index_url,headers=headers)
resp = opener.open(index_req)
print(resp.read().decode())

爬虫保存与读取cookie

我们可以利用本模块的http.cookiejar.CookieJar类的对象来捕获cookie并在后续连接请求时重新发送,比如可以实现模拟登录功能。该模块主要的对象有CookieJar、FileCookieJar、MozillaCookieJar、LWPCookieJar

from urllib.request import Request,urlopen,HTTPCookieProcessor
from fake_useragent import UserAgent
from http.cookiejar import MozillaCookieJar

def save_cookie():
    url = 'https://www.kuaidaili.com/login/'
    headers = {
        'User-Agent':UserAgent().chrome
    }
    # 发送请求,用于登录用户
    data = {
        'next': '/',
        'login_type': '1',
        'username': '398707160@qq.com',
        'passwd': '111111111',
    }
    tru_data = urlencode(data).encode()
    req = Request(url,data=tru_data,headers=headers)
    # 创建保存cookie的对象
    cookie_jar = MozillaCookieJar()
    handler = HTTPCookieProcessor(cookie_jar)
    opener = build_opener(handler)
    resp = opener.open(req)
    cookie_jar.save('cookie.txt',ignore_discard=True,ignore_expires=True)

def load_cookie():
    # 发送请求,获取数据
    index_url = 'https://www.kuaidaili.com/usercenter/overview'
    index_req = Request(index_url,headers=headers)
    # 加载cookie
    cookie_jar = MozillaCookieJar()
    cookie_jar.load('cookie.txt',ignore_discard=True,ignore_expires=True)
    handler = HTTPCookieProcessor(cookie_jar)
    resp = opener.build_opener(handler).open(index_req)
    print(resp.read().decode())

if __name__ == '__main__':
    save_cookie()
    load_cookie()

保存的cookie有有效期,如果cookie过期,则需要重新登录获取。

urllib的异常处理

from urllib.request import Request,urlopen
from urllib.error import URLError,HTTPError
from fake_useragent import UserAgent

url = 'https://www.itbaizhan.com/stages/id/xxssee'
headers = {
    'User-Agent':UserAgent().chrome
}
req = Request(url,headers=headers)
try:
    resp = urlopen(req)
    print(resp.read().decode())
except URLError as e:
    if e.args:
        # 打印状态码
        print(e.args[0].errno)
    else:
        print(e.code)
print('爬取完成')

requests模块

pip install requests
import requests
from fake_useragent import UserAgent

def requests_get():
    url = 'https://www.baidu.com/s'
    headers = {
        'User-Agent':UserAgent().chrome
    }
    params = {
        'wd':'python爬虫'
    }
    try:
        response = requests.get(url,headers=headers,params=params)
        print(response.text)
    except requests.exceptions.RequestException as e:
        print(e)

def requests_post():
    url = 'https://www.kuaidaili.com/login/'
    headers = {
        'User-Agent':UserAgent().chrome
    }
    data = {
        'next': '/',
        'login_type': '1',
        'username': '398707160@qq.com',
        'passwd': '111111111',
    }
    try:
        response = requests.post(url,headers=headers,data=data)
        print(response.text)
    except requests.exceptions.RequestException as e:
        print(e)

requests伪装爬虫

  1. User-Agent:浏览器的标识,可以伪装成浏览器,让网站认为是浏览器访问。
import requests
from fake_useragent import UserAgent

def requests_get():
    url = 'http://httpbin.org/get'
    headers = {'User-Agent':UserAgent().chrome}
    resp = requests.get(url,headers=headers)
    print(resp.text)

def requests_proxy():
    url = 'http://httpbin.org/get'
    headers = {'User-Agent':UserAgent().chrome}
    proxy = {
        'http': 'http://101.10.13.10:3128'
    }
    resp = requests.get(url,headers=headers,proxies=proxy)

设置超时时间

可以通过timeout属性设置超时时间,一旦超过这个时间还没获得响应内容,就会提示错误

url = 'http://github.com'
headers = {'User-Agent':UserAgent().chrome}
resp = requests.get(url,headers=headers, timeout=0.001)
print(resp.text)

session自动保存cookies

seesion的意思是保持一个会话,比如 登陆后继续操作(记录身份信息) 而requests是单次请求的请求,身份信息不会被记录

import requests
from fake_useragent import UserAgent

def requests_session():
    url = 'https://www.kuaidaili.com/login/'
        headers = {
            'User-Agent':UserAgent().chrome
        }
        data = {
            'next': '/',
            'login_type': '1',
            'username': '398707160@qq.com',
            'passwd': '111111111',
        }
        # 创建一个session对象 
        s = requests.Session() 
        response = s.post(url,headers=headers,data=data)
        # 发送请求,获取数据
        index_url = 'https://www.kuaidaili.com/usercenter/overview'
        index_req = Request(index_url,headers=headers)
        response = s.get(index_url,headers=headers)

# 用session对象发出get请求,设置cookies 
s.get('http://httpbin.org/cookies/set/sessioncookie/123456789') 

ssl验证

# 禁用安全请求警告
requests.packages.urllib3.disable_warnings()
resp = requests.get(url, verify=False, headers=headers)

获取响应信息的方法

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2113464.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【redis】数据量庞大时的应对策略

文章目录 为什么数据量多了主机会崩分布式系统应用数据分离架构应用服务集群架构负载均衡器数据库读写分离 引入缓存冷热分离架构 分库分表微服务是什么代价优势 为什么数据量多了主机会崩 一台主机的硬件资源是有上限的,包括但不限于一下几种: CPU内存…

【最新华为OD机试E卷-支持在线评测】猜字迷(100分)-多语言题解-(Python/C/JavaScript/Java/Cpp)

🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-E/D卷的三语言AC题解 💻 ACM金牌🏅️团队| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 🍿 最新华为OD机试D卷目录,全、新、准,题目覆盖率达 95% 以上,…

.hmallox、.rmallox勒索病毒揭秘:如何保护你的数据免受威胁

导言 .hmallox、.rmallox勒索病毒是一种加密型勒索病毒,以其特定的加密机制和传播方式而闻名。它主要通过钓鱼邮件或恶意下载链接感染计算机系统。一旦入侵系统,它会加密受害者的文件,并要求支付赎金以恢复数据。了解 .hmallox 、.rmallox勒…

2024数学建模国赛选题建议+团队助攻资料(已更新完毕)

目录 一、题目特点和选题建议 二、模型选择 1、评价模型 2、预测模型 3、分类模型 4、优化模型 5、统计分析模型 三、white学长团队助攻资料 1、助攻代码 2、成品论文PDF版 3、成品论文word版 9月5日晚18:00就要公布题目了,根据历年竞赛题目…

解决npm i 安装报npm ERR! code E401

1、前端去维护项目时,通过 git clone 下来以后,经常是直接 npm i 去安装项目需要的依赖,但是往往很多项目不是我们自己写的,或者从 GitHub 上面 clone 的开源项目,这个时候出现问题就很难处理,这里分享下安…

java基础-线程实现

文章目录 什么是线程线程的基本特性线程的状态线程的调度 线程的实现方式1. 继承 Thread 类2. 实现 Runnable 接口3. 使用 Callable 和 Future4. 使用 ExecutorService总结 什么是线程 线程(Thread)是计算机科学中的一个重要概念,它是操作系…

EmguCV学习笔记 C# 9.2 VideoWriter类

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。 教程VB.net版本请访问…

【数据结构】--初识泛型

1. 包装类 在Java中,由于基本类型不是继承自Object,为了在泛型代码中可以支持基本类型,Java给每个基本类型都对应了一个包装类型。 1.1 基本数据类型和对应的包装类 除了 Integer 和 Character, 其余基本类型的包装类都是首字母…

1051 找矩阵中的鞍点

### 思路 1. 输入一个3行4列的整数矩阵。 2. 遍历每一行,找到每一行的最大值及其列索引。 3. 检查该列索引对应的列中是否是最小值。 4. 如果是,则输出该值;如果没有找到鞍点,输出“NO”。 ### 伪代码 1. 初始化一个3行4列的矩阵…

SLT—List详解

1.list概述 相较于 vector 的连续线性空间,list 就显得复杂很多,它的好处是每次插入或删除一个数据,就配置或释放一个元素空间。因此,list 对于空间的运用有绝对的精准,一点也不浪费。对于任何位置的元素进行插入或者元…

连续信号的matlab表示

复习信号与系统以及matlab 在matlab中连续信号使用较小的采样间隔来表四 1.单位阶跃信号 阶跃信号:一个理想的单位阶跃信号在时间 t 0 之前值为0,在 t 0 及之后值突然变为常数 A(通常取 A 1) %matlab表示连续信号,是让信号的采样间隔很小…

WebGIS面试题(第九期)

坐标系: 文章目录 **坐标系:**1、如何使用ArcGIS进行GIS坐标系转换?2、Cesium中的Cartesian3坐标系的原点在哪里?它的轴是如何定义的?3、如何在Cesium中使用矩阵进行坐标系转换。4、在Cesium中,如何将屏幕坐…

在VScode上写网页(html)

一、首先点进VScode,下载3个插件。 VScode安装:VScode 教程 | 菜鸟教程 二、新建 HTML 文件 作者运行的代码来自:http://t.csdnimg.cn/vIAQi 把代码复制粘贴进去,然后点击文件→另存为→选择html格式。 三、运行代码

笔试强训,[NOIP2002普及组]过河卒牛客.游游的水果大礼包牛客.买卖股票的最好时机(二)二叉树非递归前序遍历

目录 [NOIP2002普及组]过河卒 牛客.游游的水果大礼包 牛客.买卖股票的最好时机(二) 二叉树非递归前序遍历 [NOIP2002普及组]过河卒 题里面给的提示很有用,那个马的关系,后面就注意,dp需要作为long的类型。 import java.util.Sc…

店匠科技携手Stripe共谋电商支付新篇章

在全球电商行业蓬勃发展的背景下,支付环节作为交易闭环的核心,其重要性日益凸显。随着消费者对支付体验要求的不断提高,以及跨境电商的迅猛发展,支付市场正经历着前所未有的变革与挑战。在这一充满机遇与竞争的领域,店匠科技(Shoplazza)凭借其创新的嵌入式支付解决方案—— Sho…

[米联客-XILINX-H3_CZ08_7100] FPGA程序设计基础实验连载-39 HDMI视频输入测试

软件版本:VIVADO2021.1 操作系统:WIN10 64bit 硬件平台:适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA 实验平台:米联客-MLK-H3-CZ08-7100开发板 板卡获取平台:https://milianke.tmall.com/ 登录“米联客”FPGA社区 http…

软考(计算机技术与软件专业技术资格(水平)考试)

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…

《JavaEE进阶》----11.<SpringIOCDI【Spring容器+IOC详解+DI介绍】>

本篇博客会详细讲解什么是Spring。 SpringIOC SpringID 五个类注解:Controller、Service、Repository、Component、Configuration 一个方法注解:Bean 什么是Spring IOC容器 Spring 是包含众多工具的IOC容器。能装东西的容器。 1.容器 如我们之前学的 Tom…

高效传输秘籍,揭秘Rsync和SCP的优劣,助你做出明智选择!

在日常的运维工作中,文件传输任务频繁出现,而选择合适的工具能显著提高工作效率。Rsync 和 SCP 是两款常见的文件传输工具,但它们各具优缺点,适合不同的场景。本文将通过深入分析这两款工具的特性、使用场景和性能,帮助…

Django+Vue3前后端分离学习(一)(项目开始时settings.py里的设置)

一、创建django项目 二、修改settings.py里的配置: 1、修改语言和时区: # 语言编码 LANGUAGE_CODE zh-hansTIME_ZONE UTCUSE_I18N True# 不用时区 USE_TZ False 2、配置数据库: DATABASES {default: {ENGINE: django.db.backends.m…