Python爬虫基础1_urllib库1

发布于:2022-11-28 ⋅ 阅读:(211) ⋅ 点赞:(0)

1.urllib库

(1)一个爬虫的基本架构:

第一步,需要锁定url

url='(填写url地址)'

对了,这里解析一下url的构成,这里只举一个简单的例子

比如:aspxfans.com

http:是协议,用//分隔(URL必须部分)

www.baidu.com是主机域名(URL必须部分)

端口号是8080,用:分隔

/news/是虚拟目录部分,从域名后的第一个/一直到最后一个/

从域名后的最后一个/到?之前的index.asp是文件名部分

?后面,#之前的是参数部分,参数之间用&作为分隔符

#之后的name是锚部分

(感觉学到了好多东西!!)

第二步,模拟浏览器给服务器发送请求

import urllib.request
response = urllib.request.urlopen(url)

这里需要调用的是urllib.request里的urlopen方法,传入的参数是之前设置的url

这个response的格式是HTTPResponse,我的理解是response是我们发送请求后,从服务端发回来的数据

第三步,读取接收到的数据

response.read() #方法1:一个字节一个字节读取
response.read(填一个数字) #方法2:设置一共读取多少个字节
response.readline() #方法3:读取一行
response.readlines() #方法4:一行一行读,全部读完
response.getcode() #方法5:获取本次请求的状态码
response.geturl() #方法6:获取本次请求的url
response.getheaders() #方法7:获取本次请求的响应头,是一些状态信息

在接收到数据以后我们需要对数据进行解码,具体方法为在response.read等方法后面添加.decode()方法并把参数设置为('utf-8')

下面以response.read()方法为例:

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

第四步,我们打印获取到的页面信息即可

print(context)

PS:反爬手段1

很多网站都有反爬手段,但是我们也有反反爬手段(xixi),我学到的第一个反爬手段是——定制请求对象User-Agent

首先,User-Agent可以通过F12键开发者工具在浏览器中获取

我们需要在获取UA之后,把它复制到Python中来,但是要注意的是复制过来以后不能直接用,要新建一个字典并把我们的UA放进去

这里以我的User-Agent为例

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

这样我们的字典就建好了!

那么要如何利用这个User-Agent呢?

我们不能直接在urllib.request.urlopen()中使用字典headers,但是还有其他的办法

可以使用urllib.request里的.Request方法,并把url和headers字典传进去,包装成一个新的对象,然后直接把这个对象传入到urllib.request.urlopen方法中就可以了!要注意,调用.Request()方法传参的时候,要用关键字传参的方法!具体原因和Request方法定义时的参数顺序有关

import urllib.request
url='https://www.baidu.com' #注意这里的协议变成了https
headers={
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36'
}
request=urllib.request.Request(url=url,headers=headers)
urllib.request.urlopen(request)
context=response.read().decode('utf-8')
print(context)

(2)下载文件

下载文件需要用到urllib.request中的.urlretrieve方法

urllib.request.urlretrieve(url,'文件名')

文件名记得加后缀!(就是.html .mp4 .jpg啥的,比如'baidu.html' 'baidu.jpg' 'baidu.mp4')

(3)urllib中get请求的quote方法

下面我们来看一个例子:

我的需求是,在百度页面搜索周杰伦,并获取这个页面的全部信息

首先,在百度页面(chrome)搜素周杰伦,并且把网页的url复制到了pycharm中,

得到的结果是:

https://www.baidu.com/swd=
%E5%91%A8%E6%9D%B0%E4%BC%A6
&rsv_spt=1&rsv_iqid=0xf39203a2000030d0&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_dl=tb&rsv_enter=1&rsv_sug3=9&rsv_sug2=0&rsv_btype=i&inputT=881&rsv_sug4=881

注意,'%E5%91%A8%E6%9D%B0%E4%BC%A6'这串代码(实际上这串代码代表的就是周杰伦这三个字)在浏览器上方的导航栏中,显示的是'周杰伦'三个汉字

可以推测,在复制这个url的时候,周杰伦三个汉字被转码了,转成了Unicode编码格式

如果按照正常的流程来写,那么Pycharm中的代码是这样的:

import urllib.request
import urllib.parse
url='https://www.baidu.com/s?wd=周杰伦'
headers={
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36'
}
request=urllib.request.Request(url=url,headers=headers)
urllib.request.urlopen(request)
context=response.read().decode('utf-8')
print(context)

如果代码这样写,程序运行的时候会报错

报错的原因是,Ascii码中没有'周杰伦'这三个字!为了解决这个问题,我们需要把'周杰伦'转码成Unicode格式,这就需要用到.quote方法了

import urllib.request
import urllib.parse
url='https://www.baidu.com/s?wd='
headers={
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36'
}
​
name=urllib.parse.quote('周杰伦')
url=url+name
​
request=urllib.request.Request(url=url,headers=headers)
urllib.request.urlopen(request)
context=response.read().decode('utf-8')
print(context)

程序中添加了两行代码,对周杰伦进行转码,并对url进行了拼接

再次运行程序时,程序不会报错,并且成功的获取了页面!!

(4)urllib中get请求的urlencode方法

有时候,我们也会遇到url中有多个参数的情况,这时再用quote方法进行转码会比较麻烦,所以新的方法.urlencode()应运而生

这里还是用'周杰伦'的例子来说明

在搜索栏中,本次请求的url为百度安全验证

这里是Typora自动转码后的url

原url为 百度安全验证周杰伦&sex=男&location=中国(这也是删掉了一些后缀的url)

这里有三个参数,我们可以调用urlencode方法

import urllib.request
import urllib.parse
url='https://www.baidu.com/s?'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36'
}
data={
    'wd'='周杰伦'
    'sex'='男'
    'location'='中国'
}
data=urllib.parse.urlencode(data)
url=url+data
request=urllib.request.Request(url=url,headers=headers)
response=urllib.request.urlopen(request)
context=response.read().decode('utf-8')
print(context)

注意,urlencode方法会自动用&连接各个参数,很方便捏~

(5)post请求

上面讨论的都是get请求,那么现在我们来看看post请求

还是用一个例子来说明:

这一次,我们在百度翻译中搜索spiderman,并且要把网页放回的数据爬下来!

第一步,寻找需要的接口

首先打开F12开发者工具,然后在百度翻译搜索框中输入spiderman,发现开发者工具中的Network板块里出现了很多请求

现在我们需要在这么多的接口里面找到要用的那个,这里可以利用Payload和Preview来辅助查找

第二步,写爬虫!

找到需要的接口以后,我们就要可以开始写程序了

本次请求的url为:'https://fanyi.baidu.com/sug'

请求方式为POST

import urllib.request
import urllib.parse
import json
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/100.0.4896.75 Safari/537.36'
}
data={
    'kw': 'spiderman'
}#data是参数列表,可以在Payload中找到
data=urllib.parse.urlencode(data).encode('utf-8')#注意,POST请求必须要编码,编码之后必须要调用encode方法
request=urllib.request.Request(url=url,headers=headers,data=data)
response=urllib.request.urlopen(request)
context=response.read().decode('uft-8')
​
obj=json.loads(context)#把string类型的context转成json格式
print(obj)

PS:反爬手段2

在百度翻译中,有一个详细翻译的接口,这次我们需要获取详细翻译里的数据

import urllib.request
import urllib.parse
import json
url='https://fanyi.baidu.com/v2transapi?from=en&to=zh'
headers={
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36'
}
data = {
    'from': 'en',
    'to': 'zh',
    'query': 'spiderman',
    'simple_means_flag': '3',
    'sign': '558153.812920',
    'token': 'e0c97757d7e68e653ff1823e830d703a',
    'domain': 'common',
}
data=urllib.parse.urlencode(data).encode('utf-8')
​
request=urllib.request.Request(url=url,headers=headers,data=data)
response=urllib.request.urlopen(request)
context=response.read().decode('uft-8')
​
obj=json.loads(context)
print(obj)

如果程序这样写,虽然不会报错,但是网页返回的数据会是这样的:

{'errno': 997, 'errmsg': '未知错误', 'query': 'spiderman', 'from': 'en', 'to': 'zh', 'error': 997}

这里出现这些数据的原因是,我们遇到了百度翻译的反爬!为了解决这个问题,需要用到F12开发者工具中Headers模块里面的Request Headers中的Cookie属性,并把它加到headers中

import urllib.request
import urllib.parse
import json
​
url = 'https://fanyi.baidu.com/v2transapi?from=en&to=zh'
headers = {
    'Cookie': 'BIDUPSID=F7A7310A7E8804BC9BD32DB49C96F606; PSTM=1632744430; BAIDUID=B255CFC208EA74A0EF892B1DD6E29DF9:FG=1; BDUSS=pUZjlnRWxIWXl5UEJZM3dJcEN1N3FxfkVKU2Z-a1N3Q052bjdidTRaa3VBM1ZpRVFBQUFBJCQAAAAAAAAAAAEAAADHJpxJtPPLp7jnMTAwMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC52TWIudk1iNG; BDUSS_BFESS=pUZjlnRWxIWXl5UEJZM3dJcEN1N3FxfkVKU2Z-a1N3Q052bjdidTRaa3VBM1ZpRVFBQUFBJCQAAAAAAAAAAAEAAADHJpxJtPPLp7jnMTAwMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC52TWIudk1iNG; BAIDUID_BFESS=B255CFC208EA74A0EF892B1DD6E29DF9:FG=1; BA_HECTOR=8g2lag8ka0a00hak2h219c8m1hk2fa71b; ZFY=h55hXF9vHDVbAp77UC3vul6mu5:AyI2YhYfQNbE6jdlQ:C; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; APPGUIDE_10_0_2=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; REALTIME_TRANS_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1665234429,1665234543; ab_sr=1.0.1_NzcyZDM5NDJlYTAwMTkzYjUwMzZlNzMyMjU1NDNiZDQ0ZjI2NTNhMTc0NGM1OGMxZTE0NzZmNmU4YWMxNTU4ZDRiMTM5ZTAzNjhhMWJjYTRhNjAzNWJhNzk3ZGZiODMzNDVjYzIxM2ViNjBiMmVjZTA1YjNiZmYwODViYTY2ODRiMzc5MjI5OTI1YjQ1NTMxOTExZDM2ZmExOTFjMjk1MGNlZWYxZDQ5YzEzNThkYmQwZDcwYmE5YzM5NzNkNDQ3; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1665239308',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36'
}
data = {
    'from': 'en',
    'to': 'zh',
    'query': 'spiderman',
    'simple_means_flag': '3',
    'sign': '558153.812920',
    'token': 'e0c97757d7e68e653ff1823e830d703a',
    'domain': 'common',
}
data = urllib.parse.urlencode(data).encode('utf-8')
​
request = urllib.request.Request(url=url, data=data, headers=headers)
response = urllib.request.urlopen(request)
context = response.read().decode('utf-8')
​
print(json.loads(context))

有了Cookie以后,我们就可以获取到详细翻译的数据了!(反反爬成功!)

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到