python爬虫4(Urlib)

html

在学习爬虫前,我们需要对html中的标签有一个简单的了解
< table >:表格
< tr > :表格中的行
< td >:表格中的列
< ul > < li >无序列表 爬虫的使用场景非常之多–>
< ol >< li >有序列表

示例如下

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <!--  table  表格
          tr     行
          td     列
    -->
        <table width="200px" height="200px" border="1px">
            <tr>
                <td>
                    姓名
                </td>
                <td>
                    年龄
                </td>
                <td>
                    性别
                </td>
            </tr>

            <tr>
                <td>
                    张三
                </td>

                <td>
                    18
                </td>

                <td></td>
            </tr>
        </table>

<!--        ul  li 无序列表  爬虫的使用场景非常之多-->

        <ul>
            <li>铁锅炖大鹅</li>
            <li>小鸡炖蘑菇</li>
            <li>锅包肉</li>
        </ul>

<!--        ol li-->

        <ol>
            <li>穿上衣服</li>
            <li>下床</li>
            <li>洗漱</li>
        </ol>

    <a href="http://www.baidu.com/">百度</a>

    </body>
</html>

效果图如下
在这里插入图片描述

urllib库使用

urllib库是python本身自带的库函数

# 使用urllib来获取百度首页的源码

import urllib.request

# 定义一个Url 就是你要访问的地址
url='http://www.baidu.com'

#模拟浏览器向服务器发送请求 response响应
response=urllib.request.urlopen(url)

#获取页面的源码 使用content保存
content=response.read()

#打印数据
print(content)

read方法 返回的是字节形式的二进制数据
我们要将二进制的数据转换为字符串
解码

decode('编码的格式')

示例如下

# 使用urllib来获取百度首页的源码

import urllib.request

# 定义一个Url 就是你要访问的地址
url='http://www.baidu.com'

#模拟浏览器向服务器发送请求 response响应
response=urllib.request.urlopen(url)

#获取页面的源码 使用content保存
content=response.read().decode('utf-8')

#打印数据
print(content)

urllib的基本使用

服务器返回的类型

import urllib.request

url='http://www.baidu.com'

#模拟浏览器向服务器发送请求 response响应
respose=urllib.request.urlopen(url)


#类型
print(type(respose))

输出结果为

<class 'http.client.HTTPResponse'>

由此可知response的数据类型是HttpResponse

read

read() 字节形式读取二进制
扩展:rede(n)返回前n个字节

import urllib.request

url='http://www.baidu.com'

#模拟浏览器向服务器发送请求 response响应
respose=urllib.request.urlopen(url)

#按照一个字节一个字节的去读
content=respose.read()

print(content)

reline

readline() 读取一行

import urllib.request

url='http://www.baidu.com'

#模拟浏览器向服务器发送请求 response响应
respose=urllib.request.urlopen(url)

content=respose.readline()

print(content)

relines

readlines() 一行一行读取 直至结束

import urllib.request

url='http://www.baidu.com'

#模拟浏览器向服务器发送请求 response响应
respose=urllib.request.urlopen(url)

content=respose.readlines()

print(content)

getcode

getcode() 获取状态码
当输出是200时表示没有问题

import urllib.request

url='http://www.baidu.com'

#模拟浏览器向服务器发送请求 response响应
response=urllib.request.urlopen(url)

print(response.getcode())

geturl

geturl() 获取url

import urllib.request

url='http://www.baidu.com'

#模拟浏览器向服务器发送请求 response响应
response=urllib.request.urlopen(url)
print(response.geturl())

getheaders

getheaders() 获取一些状态信息

import urllib.request

url='http://www.baidu.com'

#模拟浏览器向服务器发送请求 response响应
response=urllib.request.urlopen(url)
print(response.getheaders())

urllib-下载

下载我们需要使用

urllib.request.urlretrieve()

网页

import urllib.request

#下载网页
url_page='http://www.baidu.com'

#参数1 url表示下载的地址 参数2 filename表示文件的名字
urllib.request.urlretrieve(url=url_page,filename='baidu.html')

图片

我们在网上找到想要下载的图片
复制图片链接后
使用urllib.request.urlretrieve()

import urllib.request


#参数1 url表示下载的地址 参数2 filename表示文件的名字
#下载图片
url_image='https://tse1-mm.cn.bing.net/th/id/OIP-C.nrP2Hi-wqMS2Xq4h3JvxAQHaNK?w=115&h=180&c=7&r=0&o=5&dpr=1.3&pid=1.7'
urllib.request.urlretrieve(url=url_image,filename='huoyin.jpg')#注意需要有后缀

视频

我们随意找到一个视频
找到视频之后我们需要暂停视频,
鼠标右键,点击检查
在检查页面找到这个图标在这里插入图片描述
之后点击页面中的该视频
在这里插入图片描述
如图,我们已经定好了位置,视频中的src即为视频的地址
在这里插入图片描述

#下载视频
url_video='https://vdept3.bdstatic.com/mda-qdv3k5dkmivi7zr3/sc/cae_h264/1714876360957548870/mda-qdv3k5dkmivi7zr3.mp4?v_from_s=hkapp-haokan-hna&auth_key=1715453205-0-0-9205b31f8ea8e2324cad3c43f607c005&bcevod_channel=searchbox_feed&cr=2&cd=0&pd=1&pt=3&logid=2805875064&vid=9797222881313443257&klogid=2805875064&abtest='
urllib.request.urlretrieve(url=url_video,filename='shiping.mp4')
#注意后缀,同时注意pycharm中是没有视频播放器的,我们需要找到该文件的文件路径,去播放他

urllib-请求对象的定制

import urllib.request
url='https://www.baidu.com'

#url的组成
#https://www.baidu.com/s?wd=周杰伦

#    协议            主机           端口号    路径    参数         锚点
# http/https    www.baidu.com    80/443     s     wd=周杰伦         #
# http 80
# https 443
# mysql 3306
# oracle 1521
# redis 6379
# mongodb 27017

#https比http更加安全 https中加了一个叫ssl的东西
response=urllib.request.urlopen(url)

#获取网页源码
content=response.read().decode('utf-8')
print(content)

当我们使用https获取网页源码时,我们会发现我们获取的网页源码极少,原因是我们遭到了第一个反爬UA

UA介绍:User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统
及版本、CPU 类型、浏览器及版本。浏览器内核、浏览器渲染引擎、浏览器语言、浏览器插件等
语法:request = urllib.request.Request()

UA获取

  • 可以百度UA大全,获取各个浏览器的UA

  • 我们可以在浏览器页面右键找到检查
    在这里插入图片描述
    在检查页面找到network
    在这里插入图片描述
    刷新一下页面
    找到我们接口/域名
    在这里插入图片描述
    我们点击我们接口/域名
    然后点击headers划到headers页面的最下面
    找到
    User-Agent
    在这里插入图片描述
    里面可以看到我们的操作系统等各种信息
    我们将其复制下来

    我们使用请求对象的定制对其进行伪装,让我们在爬虫时使浏览器能够辨识到操作系统等各个参数

import urllib.request
url='https://www.baidu.com'

#使用字典保存我们获取的ua数据
headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'}

#因为urlopen方法中不能存储字典 所以headers不能传递进去
# 这时候我们就使用到了请求对象的定制,将其变成一个整体
# 注意 因为参数顺序问题 不能直接写url和headers 因为这两个参数中间还有data参数
# 所以我们使用的是关键字传参
request=urllib.request.Request(url=url,headers=headers)

response=urllib.request.urlopen(request)

#获取网页源码
content=response.read().decode('utf-8')
print(content)

编解码

如图我们收索一个歌星
我们将链接中歌星名字后面的地址删除掉后将链接复制到pycharm上
在这里插入图片描述

我们会发现在pycharm上变成了下面的形式

https://www.baidu.com/s?ie=utf-8&f=3&rsv_bp=1&rsv_idx=1&tn=baidu&wd=%E5%91%A8%E6%9D%B0%E4%BC%A6

将歌星的名字变成了其他的东西
其实他是将其变成了Unicode编码

==编码集的演变‐‐‐
由于计算机是美国人发明的,因此,最早只有127个字符被编码到计算机里,也就是大小写英文字母、数字和一些符号,
这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122。
但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,
所以,中国制定了GB2312编码,用来把中文编进去。
你可以想得到的是,全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc‐kr里,
各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。
因此,Unicode应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。
Unicode标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。
现代操作系统和大多数编程语言都直接支持Unicode。

1.get请求方式:urllib.parse.quote()


#需求 获取https://www.baidu.com/s?ie=utf-8&f=3&rsv_bp=1&rsv_idx=1&tn=baidu&wd=周杰伦的网页源码
import urllib.request
url='https://www.baidu.com/s?ie=utf-8&f=3&rsv_bp=1&rsv_idx=1&tn=baidu&wd=周杰伦'

#请求对象的定制是为了解决反爬的第一种手段
headers={
    'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'
}#找到页面的ua

#请求对象的定制
request=urllib.request.Request(url=url,headers=headers)#关键字传参

#模拟浏览器向服务器发送请求
response=urllib.request.urlopen(request)

#获取响应的内容
content=response.read().decode('utf-8')

#打印数据
print(content)

我们运行上面的代码会发现报错了,原因是url链接后面的wd后面不能是汉字,需要变为Unicode编码

我们将汉字变为我们的Unicode编码需要使用到get的请求方法

get请求方式:urllib.parse.quote()

我们需要导入import urllib.parse

#需求 获取https://www.baidu.com/s?ie=utf-8&f=3&rsv_bp=1&rsv_idx=1&tn=baidu&wd=周杰伦的网页源码
import urllib.request
import urllib.parse

url='https://www.baidu.com/s?ie=utf-8&f=3&rsv_bp=1&rsv_idx=1&tn=baidu&wd='

#请求对象的定制是为了解决反爬的第一种手段
headers={
    'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'
}#找到页面的ua

#将周杰伦三个字变成Unicode编码格式
#我们需要依赖于urllib.parse
name=urllib.parse.quote('周杰伦')
url=url+name

#请求对象的定制
request=urllib.request.Request(url=url,headers=headers)#关键字传参

#模拟浏览器向服务器发送请求
response=urllib.request.urlopen(request)

#获取响应的内容
content=response.read().decode('utf-8')

#打印数据
print(content)

2.get请求方式:urllib.parse.urlencode()

在这里插入图片描述

当链接中有多个中文参数时,使用quote可能会有些麻烦,这时候我们就可以使用urlencode方式

#urlencode应用场景:当链接中有多个中文参数时

#需求:将下面的汉字转换成unicode编码
#https://www.baidu.com/s?ie=utf-8&f=3&rsv_bp=1&rsv_idx=1&tn=baidu&wd=周杰伦&sex=男

import urllib.parse
data={
    'wd':'周杰伦',
    'sex':'男'
}
#   在转换为unicode中
#   :对应=
#   ,对应&
a=urllib.parse.urlencode(data)
print(a)


#需求: 获取https://www.baidu.com/s?ie=utf-8&f=3&rsv_bp=1&rsv_idx=1&tn=baidu&wd=%E5%91%A8%E6%9D%B0%E4%BC%A6&sex=%E7%94%B7的网页源码
import urllib.request
import urllib.parse

base_url='https://www.baidu.com/s?ie=utf-8&f=3&rsv_bp=1&rsv_idx=1&tn=baidu'

data={
    'wd':'周杰伦',
    'sex':'男'
}

new_data=urllib.parse.urlencode(data)

#请求资源路径
url=base_url+new_data

headers={
    'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'
}#找到页面的ua

#请求对象的定制
request=urllib.request.Request(url=url,headers=headers)

#模拟浏览器向服务器发送请求
response=urllib.request.urlopen(request)

#获取网页源码的数据
content=response.read().decode('utf-8')

print(content)

3.post请求百度翻译

但我们打开百度翻译,右键检查,network,在翻译页面输入spider,我们会发现每输入一个字母network页面都会变化,我们会发现左侧有很多sug,我们依次点击每个sug和payload,我们会发现其逐渐组成了一个spider单词。
在这里插入图片描述
我们点击preview可以发现里面是spider的翻译
在这里插入图片描述
所以我们在爬虫中的难点就是哪个数据才是我想要的数据

我们可以使用post找到我们想要的数据
我们以百度翻译为例,找到我们输入的单词

我们在headers中找到Request URL,复制该地址
在这里插入图片描述

# post请求方式的参数 必须编码   data = urllib.parse.urlencode(data)
# 编码之后 必须调用encode方法 data = urllib.parse.urlencode(data).encode('utf-8')
# 参数是放在请求对象定制的方法中  request = urllib.request.Request(url=url,data=data,headers=headers)
# _*_ coding : utf-8 _*_
# @Time : 2024/5/12 下午8:54
# @Author : xtone
# @File : 059_尚硅谷_爬虫_urllib_post请求百度翻译
# @Project : pythonProject
import urllib.request
import urllib.parse
url='https://fanyi.baidu.com/sug'

headers={
   'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'
}#找到页面的ua

#使用列表存储我们需要查找的单词
data={
   'kw':'spider'
}

# Request参数中的data数据为字节类型,所以我们需要对data数据encode
# post请求的参数必须进行编码 encode()编码并指定编码的类型 decode()解码
data=urllib.parse.urlencode(data).encode('utf-8')

#post请求的参数 是不会拼接在url后面的 而是需要放在请求对象定制的参数中
#post请求的参数必须编码
request=urllib.request.Request(url=url,data=data,headers=headers)

#模拟浏览器向服务器发送请求
response=urllib.request.urlopen(request)

#获取响应的数据
content=response.read().decode('utf-8')


print(content)
print(type(content))#数据类型是str

输出结果为
在这里插入图片描述
我们可以发现数据类型是字符串类型
此时我们需要让字符串–>json对象

# _*_ coding : utf-8 _*_
# @Time : 2024/5/12 下午8:54
# @Author : xtone
# @File : 059_尚硅谷_爬虫_urllib_post请求百度翻译
# @Project : pythonProject
import urllib.request
import urllib.parse
url='https://fanyi.baidu.com/sug'

headers={
    'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'
}#找到页面的ua

#使用列表存储我们需要查找的单词
data={
    'kw':'spider'
}

# Request参数中的data数据为字节类型,所以我们需要对data数据encode
# post请求的参数必须进行编码 encode()编码并指定编码的类型 decode()解码
data=urllib.parse.urlencode(data).encode('utf-8')

#post请求的参数 是不会拼接在url后面的 而是需要放在请求对象定制的参数中
#post请求的参数必须编码
request=urllib.request.Request(url=url,data=data,headers=headers)

#模拟浏览器向服务器发送请求
response=urllib.request.urlopen(request)

#获取响应的数据
content=response.read().decode('utf-8')

#
# print(content)
# print(type(content))#数据类型是str
import json
obj=json.loads(content)
print(obj)

经过转换后,我们可以发现打印出了我们想要的preview了

4.post请求百度翻译之详细翻译

本小节内容出现错误,因为百度翻译的反爬手段升级了
我们打开百度翻译,我们来翻译love这个单词,跟上次一样我们右键检查,我们找到sug
在这里插入图片描述
我们关注sug的payload
在这里插入图片描述

我们点到translate找到详细翻译,我们查看详细翻译的payload我们发现比sug上多了很多数据
在这里插入图片描述
其实百度翻译中还有一个反爬手段,我们找到他的接口,我们将其复制过来
在这里插入图片描述
我们将其中的参数复制到pycharm中
在这里插入图片描述

# _*_ coding : utf-8 _*_
# @Time : 2024/5/13 下午6:07
# @Author : xtone
# @File : 060_尚硅谷_爬虫_urllib_post请求百度翻译之详细翻译
# @Project : pythonProject
import urllib.request
import urllib.parse

#将接口复制过来
url='https://fanyi.baidu.com/ait/text/translate'

headers={
    'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'
}#找到页面的ua

#payload中的参数,使用正则替换
data={"query":"love",
      "from":"en","to":"zh",
      "reference":"",
      "corpusIds":[],
      "qcSettings":["1","2","3","4","5","6","7","8","9","10","11"],
      "needPhonetic":"true","domain":"common","milliTimestamp":"1715595474705"
      }
#post请求的参数 必须进行编码 并且要调用encode方法
data=urllib.parse.urlencode(data).encode('utf-8')

#请求对象的定制
request=urllib.request.Request(url=url,data=data,headers=headers)

#模拟浏览器向服务器发送请求
response=urllib.request.urlopen(request)

#获取响应的数据
content=response.read().decode('utf-8')

print(content)

我们发现上面代码只得到了部分的数据
在这里插入图片描述
我们试试使用json转换成为json对象

#使用json转换
import json
obj=json.loads(content)
print(obj)

发现出现了未知错误,其实是在headers我们需要给到cookie



import urllib.request
import urllib.parse

url = 'https://fanyi.baidu.com/v2transapi?from=en&to=zh'

headers = {
    # 'Accept': '*/*',
    # 'Accept-Encoding': 'gzip, deflate, br',
    # 'Accept-Language': 'zh-CN,zh;q=0.9',
    # 'Connection': 'keep-alive',
    # 'Content-Length': '135',
    # 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
    'Cookie': 'BIDUPSID=DAA8F9F0BD801A2929D96D69CF7EBF50; PSTM=1597202227; BAIDUID=DAA8F9F0BD801A29B2813502000BF8E9:SL=0:NR=10:FG=1; __yjs_duid=1_c19765bd685fa6fa12c2853fc392f8db1618999058029; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; BDUSS=R2bEZvTjFCNHQxdUV-cTZ-MzZrSGxhbUYwSkRkUWk2SkxxS3E2M2lqaFRLUlJoRVFBQUFBJCQAAAAAAAAAAAEAAAA3e~BTveK-9sHLZGF5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFOc7GBTnOxgaW; BDUSS_BFESS=R2bEZvTjFCNHQxdUV-cTZ-MzZrSGxhbUYwSkRkUWk2SkxxS3E2M2lqaFRLUlJoRVFBQUFBJCQAAAAAAAAAAAEAAAA3e~BTveK-9sHLZGF5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFOc7GBTnOxgaW; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; BAIDUID_BFESS=DAA8F9F0BD801A29B2813502000BF8E9:SL=0:NR=10:FG=1; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; PSINO=2; H_PS_PSSID=34435_31660_34405_34004_34073_34092_26350_34426_34323_22158_34390; delPer=1; BA_HECTOR=8185a12020018421b61gi6ka20q; BCLID=10943521300863382545; BDSFRCVID=boDOJexroG0YyvRHKn7hh7zlD_weG7bTDYLEOwXPsp3LGJLVJeC6EG0Pts1-dEu-EHtdogKK0mOTHv8F_2uxOjjg8UtVJeC6EG0Ptf8g0M5; H_BDCLCKID_SF=tR3aQ5rtKRTffjrnhPF3-44vXP6-hnjy3bRkX4Q4Wpv_Mnndjn6SQh4Wbttf5q3RymJ42-39LPO2hpRjyxv4y4Ldj4oxJpOJ-bCL0p5aHl51fbbvbURvD-ug3-7qqU5dtjTO2bc_5KnlfMQ_bf--QfbQ0hOhqP-jBRIE3-oJqC8hMIt43f; BCLID_BFESS=10943521300863382545; BDSFRCVID_BFESS=boDOJexroG0YyvRHKn7hh7zlD_weG7bTDYLEOwXPsp3LGJLVJeC6EG0Pts1-dEu-EHtdogKK0mOTHv8F_2uxOjjg8UtVJeC6EG0Ptf8g0M5; H_BDCLCKID_SF_BFESS=tR3aQ5rtKRTffjrnhPF3-44vXP6-hnjy3bRkX4Q4Wpv_Mnndjn6SQh4Wbttf5q3RymJ42-39LPO2hpRjyxv4y4Ldj4oxJpOJ-bCL0p5aHl51fbbvbURvD-ug3-7qqU5dtjTO2bc_5KnlfMQ_bf--QfbQ0hOhqP-jBRIE3-oJqC8hMIt43f; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1629701482,1629702031,1629702343,1629704515; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1629704515; __yjs_st=2_MDBkZDdkNzg4YzYyZGU2NTM5NzBjZmQ0OTZiMWRmZGUxM2QwYzkwZTc2NTZmMmIxNDJkYzk4NzU1ZDUzN2U3Yjc4ZTJmYjE1YTUzMTljYWFkMWUwYmVmZGEzNmZjN2FlY2M3NDAzOThhZTY5NzI0MjVkMmQ0NWU3MWE1YTJmNGE5NDBhYjVlOWY3MTFiMWNjYTVhYWI0YThlMDVjODBkNWU2NjMwMzY2MjFhZDNkMzVhNGMzMGZkMWY2NjU5YzkxMDk3NTEzODJiZWUyMjEyYTk5YzY4ODUyYzNjZTJjMGM5MzhhMWE5YjU3NTM3NWZiOWQxNmU3MDVkODExYzFjN183XzliY2RhYjgz; ab_sr=1.0.1_ZTc2ZDFkMTU5ZTM0ZTM4MWVlNDU2MGEzYTM4MzZiY2I2MDIxNzY1Nzc1OWZjZGNiZWRhYjU5ZjYwZmNjMTE2ZjIzNmQxMTdiMzIzYTgzZjVjMTY0ZjM1YjMwZTdjMjhiNDRmN2QzMjMwNWRhZmUxYTJjZjZhNTViMGM2ODFlYjE5YTlmMWRjZDAwZGFmMDY4ZTFlNGJiZjU5YzE1MGIxN2FiYTU3NDgzZmI4MDdhMDM5NTQ0MjQxNDBiNzdhMDdl',
    # 'Host': 'fanyi.baidu.com',
    # 'Origin': 'https://fanyi.baidu.com',
    # 'Referer': 'https://fanyi.baidu.com/?aldtype=16047',
    # 'sec-ch-ua': '"Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"',
    # 'sec-ch-ua-mobile': '?0',
    # 'Sec-Fetch-Dest': 'empty',
    # 'Sec-Fetch-Mode': 'cors',
    # 'Sec-Fetch-Site': 'same-origin',
    # 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36',
    # 'X-Requested-With': 'XMLHttpRequest',
}

data = {
    'from': 'en',
    'to': 'zh',
    'query': 'love',
    'transtype': 'realtime',
    'simple_means_flag': '3',
    'sign': '198772.518981',
    'token': '5483bfa652979b41f9c90d91f3de875d',
    'domain': 'common',
}
# post请求的参数  必须进行编码 并且要调用encode方法
data = urllib.parse.urlencode(data).encode('utf-8')

# 请求对象的定制
request = urllib.request.Request(url = url,data = data,headers = headers)

# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)

# 获取响应的数据
content = response.read().decode('utf-8')

import json

obj = json.loads(content)
print(obj)

ajax的get请求豆瓣电影的第一页

进入豆瓣电影的第一页,我们右键检查,刷新一下页面
我们寻找network的数据,找到我们想要的第一页电影的数据
在这里插入图片描述
我们发现数据的请求方式是使用get请求
在这里插入图片描述

代码如下

# get 请求
# 获取豆瓣电影的第一页的数据并且保存起来
import urllib.request

url = 'https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&start=0&limit=20'

headers = {
    'User-Agent': ' Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
}

# 定制request
request = urllib.request.Request(url=url, headers=headers)
# 获取响应数据
response = urllib.request.urlopen(request)

context = response.read().decode('utf-8')

print(context)

我们还需要将数据下载到本地
完整代码如下,其中使用文件操作
使用open函数,可以打开一个已经存在的文件,或者创建一个新文件
再将content的内容写入文件中


# get请求
# 获取豆瓣电影的第一页的数据 并且保存起来

import urllib.request

url = 'https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&start=0&limit=20'

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}

# (1) 请求对象的定制
request = urllib.request.Request(url=url,headers=headers)

# (2)获取响应的数据
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')

# (3) 数据下载到本地
# open方法默认情况下使用的是gbk的编码  如果我们要想保存汉字 那么需要在open方法中指定编码格式为utf-8
# encoding = 'utf-8'

#第一种写法
# fp = open('douban.json','w',encoding='utf-8')
# fp.write(content)

#第二种写法
with open('douban1.json','w',encoding='utf-8') as fp:
    fp.write(content)

ajax的get请求豆瓣电影的前十页

我们通过查看每一页的数据–>查看完该页的数据之后再清空,再查看下一页的内容,我们获取1,2,3,4页top_list的Request URL

# https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&
# start=0&limit=20

# https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&
# start=20&limit=20

# https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&
# start=40&limit=20

# https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&
# start=60&limit=20

我们发现,我们可以找到url的规律

# page(页数)    1  2   3   4
# start   0  20  40  60

# start ( 规律):(page - 1)*20

导入必要的库:

  • urllib.parse 用于构建 URL
    urllib.request 用于发送 HTTP 请求和获取响应
    定义三个函数:

  • create_request(page):
    构建每个页面的 URL,包括设置 start 和 limit 参数
    设置请求头,模拟浏览器请求
    get_content(request):
    发送请求并获取响应内容
    将响应内容解码为 UTF-8 格式
    down_load(page, content):
    将响应内容保存到以 douban_.json 命名的文件中

  • 在主程序中:
    提示用户输入起始页码和结束页码
    遍历指定页码范围
    对每个页码调用 create_request(), get_content(), down_load() 函数
    完成对指定页码范围内的电影数据的爬取和保存

# _*_ coding : utf-8 _*_
# @Time : 2024/5/13 下午9:16
# @Author : xtone
# @File : 062_尚硅谷_爬虫_urllib_ajax请求豆瓣电影的前10页
# @Project : pythonProject

# https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&
# start=0&limit=20

# https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&
# start=20&limit=20

# https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&
# start=40&limit=20

# https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&
# start=60&limit=20

# page    1  2   3   4
# start   0  20  40  60

# start (page - 1)*20


# 下载豆瓣电影前10页的数据
# (1) 请求对象的定制
# (2) 获取响应的数据
# (3) 下载数据
import urllib.parse
import urllib.request

def create_request(page):
    base_url='https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&'
    new_page=(page-1)*20
    dict={
        'start':(page - 1) * 20,
        'limit':20
    }

    body=urllib.parse.urlencode(dict)
    #获取每一页的url
    new_url=base_url+body

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
    }#找到UA

    #进行对象的定制
    request=urllib.request.Request(url=new_url,headers=headers)
    return request

def get_content(request):
    #模拟浏览器向服务器发送请求
    response=urllib.request.urlopen(request)

    #获取响应的内容
    content=response.read().decode('utf-8')

    return content

def down_load(page,content):
    with open('douban_'  +  str(page)  +  '.json','w',encoding='utf-8')as fp:
        #如果需要和字符串进行拼接,+号的两端全都需要为字符串,所以我们对page进行强制类型转换
        fp.write(content)


#程序的入口
if __name__=='__main__':
    start_page=int(input('请输入起始的页码'))#输入的为字符串,我们需要进行对象的转换
    end_page=int(input('请输入结束的页码'))

    for page in range(start_page,end_page+1):
        #         每一页都有自己的请求对象的定制
        request = create_request(page)
        #         获取响应的数据
        content = get_content(request)
        #         下载
        down_load(page, content)

ajax的post请求肯德基官网

我们找到肯德基官网,我们获取北京的肯德基的前十页的餐厅
我们右键检查network可以看到其是一个post请求
在这里插入图片描述
其中我们标记的就是ajax的核心对象,由此我们可以知道我们需要使用ajax请求

我们分别获取每一页数据的url和每一页的payload,查找其中的共同的规律

#第一页
#https://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname
# cname: 北京
# pid:
# pageIndex: 1
# pageSize: 10

#第二页
#https://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname
# cname: 北京
# pid:
# pageIndex: 2
# pageSize: 10

#第三页
#https://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname
# cname: 北京
# pid:
# pageIndex: 3
# pageSize: 10
# _*_ coding : utf-8 _*_
# @Time : 2024/5/14 下午3:28
# @Author : xtone
# @File : 063_尚硅谷_爬虫_urllib_ajax请求肯德基官网
# @Project : pythonProject

#第一页
#https://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname
# cname: 北京
# pid:
# pageIndex: 1
# pageSize: 10

#第二页
#https://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname
# cname: 北京
# pid:
# pageIndex: 2
# pageSize: 10

#第三页
#https://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname
# cname: 北京
# pid:
# pageIndex: 3
# pageSize: 10

import urllib.request
import urllib.parse

def create_request(page):
    base_url='https://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname'

    data={
         'cname': '北京',
         'pid':'',
        ' pageIndex': page,
        ' pageSize': '10'
    }

    data=urllib.parse.urlencode(data).encode('utf-8')

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
    }

    request=urllib.request.Request(url=base_url,headers=headers,data=data)

    return request

def get_content(request):
    response=urllib.request.urlopen(request)
    content=response.read().decode('utf-8')
    return content

def down_load(page,content):
    with open('kfc'+str(page)+'json','w',encoding='utf-8')as fp:
        fp.write(content)


if __name__=='__main__':
    start_page=int(input("请输入起始页码"))
    end_page=int(input('请输入终止的页码'))

    for page in range(start_page,end_page+1):
        #请求对象的定制
        request=create_request(page)
        #获取网页源码
        content=get_content(request)
        #下载
        down_load(page,content)

异常.URLError\HTTPError

简介:1.HTTPError类是URLError类的子类
2.导入的包urllib.error.HTTPError urllib.error.URLError
3.http错误:http错误是针对浏览器无法连接到服务器而增加出来的错误提示。引导并告诉浏览者该页是哪里出
了问题。
4.通过urllib发送请求的时候,有可能会发送失败,这个时候如果想让你的代码更加的健壮,可以通过try‐
except进行捕获异常,异常有两类,URLError\HTTPError

import urllib.request
import urllib.error

# url = 'https://blog.csdn.net/sulixu/article/details/1198189491'

url = 'http://www.doudan1111.com'

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}

try:
    request = urllib.request.Request(url = url, headers = headers)

    response = urllib.request.urlopen(request)

    content = response.read().decode('utf-8')

    print(content)
except urllib.error.HTTPError:#当出现HTTPError错误时提示
    print('系统正在升级。。。')
except urllib.error.URLError:#当出现URLError错误时提示
    print('我都说了 系统正在升级。。。')

cookie登录

当我们进入微博的个人信息页面,我们需要获取微博的个人信息页面

import urllib.request

url = 'https://weibo.cn/6451491586/info'

headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36',
}
# 请求对象的定制
request = urllib.request.Request(url=url,headers=headers)
# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)
# 获取响应的数据
content = response.read().decode('utf-8')

# 将数据保存到本地
with open('weibo.html','w',encoding='utf-8')as fp:
    fp.write(content)

我们发现代码报错了,报错原因是网页并不是utf-8编码,我们右键查看网页源码,网页源码却显示该网页是utf-8的编码
原因是

# 个人信息页面是utf-8  但是还报错了编码错误  因为并没有进入到个人信息页面 而是跳转到了登陆页面
# 那么登陆页面不是utf-8  所以报错

这个是页面的反爬手段之一,我们右键查看微博登入网页的源码,我们发现登入页面的编码是gb2312编码,我们将编码和解码都改成gb2312
我们发现不报编码错误了,但当我们进入该网页时,登入页面一直在加载中。

那我们怎么绕过登入界面呢?

# 什么情况下访问不成功?
# 因为请求头的信息不够  所以访问不成功

我们将个人信息网页的请求头参数都给复制出来,我们一个一个去尝试看看哪个参数对解决反爬手段起决定性因素,我们发现起决定性因素的是参数中的cookie

cookie中携带着你的登陆信息  
 如果有登陆之后的cookie  
 那么我们就可以携带着cookie进入到任何页面

我们写入参数cookie一般结合referer

# referer  判断当前路径是不是由上一个路径进来的    一般情况下 是做图片防盗链
# 适用的场景:数据采集的时候 需要绕过登陆 然后进入到某个页面
# 个人信息页面是utf-8  但是还报错了编码错误  因为并没有进入到个人信息页面 而是跳转到了登陆页面
# 那么登陆页面不是utf-8  所以报错

# 什么情况下访问不成功?
# 因为请求头的信息不够  所以访问不成功

import urllib.request

url = 'https://weibo.cn/6451491586/info'

headers = {
# ':authority': 'weibo.cn',
# ':method': 'GET',
# ':path': '/6451491586/info',
# ':scheme': 'https',
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
# 'accept-encoding': 'gzip, deflate, br',
'accept-language': 'zh-CN,zh;q=0.9',
'cache-control': 'max-age=0',
#     cookie中携带着你的登陆信息   如果有登陆之后的cookie  那么我们就可以携带着cookie进入到任何页面
'cookie': '_T_WM=24c44910ba98d188fced94ba0da5960e; SUBP=0033WrSXqPxfM725Ws9jqgMF55529P9D9WFxxfgNNUmXi4YiaYZKr_J_5NHD95QcSh-pSh.pSKncWs4DqcjiqgSXIgvVPcpD; SUB=_2A25MKKG_DeRhGeBK7lMV-S_JwzqIHXVv0s_3rDV6PUJbktCOLXL2kW1NR6e0UHkCGcyvxTYyKB2OV9aloJJ7mUNz; SSOLoginState=1630327279',
# referer  判断当前路径是不是由上一个路径进来的    一般情况下 是做图片防盗链
'referer': 'https://weibo.cn/',
'sec-ch-ua': '"Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"',
'sec-ch-ua-mobile': '?0',
'sec-fetch-dest': 'document',
'sec-fetch-mode': 'navigate',
'sec-fetch-site': 'same-origin',
'sec-fetch-user': '?1',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36',
}
# 请求对象的定制
request = urllib.request.Request(url=url,headers=headers)
# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)
# 获取响应的数据
content = response.read().decode('utf-8')

# 将数据保存到本地
with open('weibo.html','w',encoding='utf-8')as fp:
    fp.write(content)

Handler处理器

为什么要学习handler?

	urllib.request.urlopen(url)
		不能定制请求头
		
	urllib.request.Request(url,headers,data)
		可以定制请求头
		
	Handler
		定制更高级的请求头(随着业务逻辑的复杂 请求对象的定制已经满足不了我们的需求(动态cookie和代理
不能使用请求对象的定制)


# 需求 使用handler来访问百度  获取网页源码

import urllib.request

url = 'http://www.baidu.com'

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}

request = urllib.request.Request(url = url,headers = headers)

# handler   build_opener  open

# (1)获取hanlder对象
handler = urllib.request.HTTPHandler()

# (2)获取opener对象
opener = urllib.request.build_opener(handler)

# (3) 调用open方法
response = opener.open(request)

content = response.read().decode('utf-8')

print(content)

上面代码和直接使用response差不了太多

代理

1.代理的常用功能?
	1.突破自身IP访问限制,访问国外站点。
	2.访问一些单位或团体内部资源
		扩展:某大学FTP(前提是该代理地址在该资源的允许访问范围之内),使用教育网内地址段免费代理服务
器,就可以用于对教育网开放的各类FTP下载上传,以及各类资料查询共享等服务。
	3.提高访问速度
		扩展:通常代理服务器都设置一个较大的硬盘缓冲区,当有外界的信息通过时,同时也将其保存到缓冲
区中,当其他用户再访问相同的信息时, 则直接由缓冲区中取出信息,传给用户,以提高访问速度。
	4.隐藏真实IP
		扩展:上网者也可以通过这种方法隐藏自己的IP,免受攻击。
2.代码配置代理
	创建Reuqest对象
	创建ProxyHandler对象
	用handler对象创建opener对象
	使用opener.open函数发送请求

代理proxies写法

#使用字典存储
proxies={
'key':'value'
'http':'主机(ip)+:+port'
}
import urllib.request

url = 'https://www.ip138.com/?jdfwkey=fkqhb1'

headers={
    'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'
}#找到页面的ua

# 请求对象的定制
request = urllib.request.Request(url = url,headers= headers)

# 模拟浏览器访问服务器
# response = urllib.request.urlopen(request)

proxies = {
    'http':'212.107.29.43:80'
}
# handler  build_opener  open
handler = urllib.request.ProxyHandler(proxies = proxies)

opener = urllib.request.build_opener(handler)

response = opener.open(request)

# 获取响应的信息
content = response.read().decode('utf-8')

# 保存
with open('daili.html','w',encoding='utf-8')as fp:
    fp.write(content)


(1)高度匿名代理不改变客户机的请求,这样在服务器看来就像有个真正的客户浏览器在访问它,
这时客户的真实IP是隐藏的,服务器端不会认为我们使用了代理。
(2)普通匿名代理能隐藏客户机的真实IP,但会改变我们的请求信息,
服务器端有可能会认为我们使用了代理。不过使用此种代理时
,虽然被访问的网站不能知道你的ip地址,但仍然可以知道你在使用代理,
当然某些能够侦测ip的网页仍然可以查到你的ip。
(3)透明代理,它不但改变了我们的请求信息,还会传送真实的IP地址。

代理池

将多个代理放在一个列表中,当使用时,随机使用其中一个代理,这样可以避免只使用一个代理而导致ip被封

import urllib.request

proxies_pool = [
    {'http':'118.24.219.151:16817111'},
    {'http':'118.24.219.151:16817222'},
]

import random

proxies = random.choice(proxies_pool)#随机选择其中一个一个代理

url = 'http://www.baidu.com/s?wd=ip'

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}

request = urllib.request.Request(url = url,headers=headers)

handler = urllib.request.ProxyHandler(proxies=proxies)

opener = urllib.request.build_opener(handler)

response = opener.open(request)

content = response.read().decode('utf-8')

with open('daili.html','w',encoding='utf-8')as fp:
    fp.write(content)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值