PYTHON 七月 18, 2019

2.根据不同请求爬取数据(get、post)

文章字数 8.5k 阅读约需 8 mins. 阅读次数 1000000


urllib库


  • urllib:python自带的一个包。模拟浏览器发送请求
  • Python2:urllib2 urllib
  • Python3:urllib.parse urllib.request
#最简单的爬虫程序
#1.指定一个url
#2.编写爬虫程序模拟浏览器发起一个请求
#3.获取数据,解析数据
import urllib.request
import urllib.parse
url='http://www.baidu.com/'
response=urllib.request.urlopen(url)
#HTTPResponse:响应对象类型
data=response.read() #获取响应回客户端的数据值(bytes)
data=data.decode()
print(data)
import urllib.request
import urllib.parse
url='http://www.baidu.com/'
response=urllib.request.urlopen(url)
#response.getcode() #状态码
#response.getheaders() #请求头信息
response.geturl() #网址
#将响应会的数据值写入磁盘进行存储
url='http://www.baidu.com/'
response=urllib.request.urlopen(url)
#HTTPResponse:响应对象类型
data=response.read().decode() #获取响应回客户端的数据值(bytes)
with open('./test/baidu.html','w') as fp:
    fp.write(data)

保存图片

  • 方式一:
#忽略证书:如果爬虫程序发起的是一个https请求,则必须执行如下代码进行证书的忽略
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
#图片,音频,视频 必须为二进制类型
image_url='https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1534761981365&di=fa19817d15b6234ce5735d5007a95367&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fimgad%2Fpic%2Fitem%2F21a4462309f79052b0ac781007f3d7ca7bcbd568.jpg'

image_response=urllib.request.urlopen(image_url)

image_data=image_response.read()

with open('./test/data.jpg','wb') as fp:
    fp.write(image_data)
  • 方式二:
    #保存图片数据的第二种方式
    url='https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1534825530753&di=3d46bfef5943bbed7b4301bc198cfc2e&imgtype=0&src=http%3A%2F%2Fwww.qqma.com%2Fimgpic2%2Fcpimagenew%2F2018%2F4%2F5%2F6e1de60ce43d4bf4b9671d7661024e7a.jpg'
    urllib.request.urlretrieve(url=url,filename='tupian.jpg')
    #   ('tupian.jpg', <http.client.HTTPMessage at 0x6166978>)

url特性:

url必须为ascii编码(字母,数字,符号)。url必须由字母,数字,下划线或者符号组成。

urllib.parse.quote()

#urllib.parse.quoteu() 可以将非ASCII的字符编码成ASCII
urllib.parse.quote('人民币')
#注意:如果使用quote的话,该函数只可以为url中非ASCII的字符进行编码
##  %E4%BA%BA%E6%B0%91%E5%B8%81
url='https://www.baidu.com/s?ie=utf-8&wd=%s'
wd=urllib.parse.quote('人民币')
url=format(url%wd)
#接下来就可以对url发起一个请求

urllib.parse.urlencode()

#制定爬去百度中任意关键字对应的页面
url='http://www.baidu.com/s?'
wd=input('enter a word:')
data={
    'ie':'utf-8',
    'wd':wd
}
#需要对url进行转码
data=urllib.parse.urlencode(data)
url+=data

response=urllib.request.urlopen(url)
filename='./test/'+wd+".html"
with open(filename,'wb') as fp:
    fp.write(response.read())

通过修改UA的值进行身份的伪装:

  • UA是存在于哪里请求
  • 需要自制定request对象
#自己编写一个请求头
header={
    "User-Agent":" Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36"
}
#Request()该函数返回一个自制定的请求对象,我们可以手动的给该请求对象中参数赋值
request=urllib.request.Request(url=url,headers=header)

urllib.request.urlopen(request)

使用爬虫爬取get请求


采用字符串拼接的方式将get请求的网址拼接起来

import urllib.request
import urllib.parse
url='http://www.baidu.com/s?'
data={
    'ie':'utf-8',
    'wd':'你好吗'
}
data=urllib.parse.urlencode(data) #将get请求后的参数存入字典,然后再用urlencode()方法将字典格式化处理,变为  ie=utf-8&wd=%E4%BD%A0%E5%A5%BD%E5%90%97 ,且为ascii码,这是url的特性
url += data #将网址拼接为完整get请求http://www.baidu.com/s?ie=utf-8&wd=%E4%BD%A0%E5%A5%BD%E5%90%97
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.5792.400 QQBrowser/10.2.2101.400'
}
request=urllib.request.Request(url,headers=headers)
response=urllib.request.urlopen(request)
print(response.read().decode())

使用爬虫爬取post请求


由于post的特点,无法通过字符串拼接url的方式进行请求

import urllib.request
import urllib.parse
post_url='https://fanyi.baidu.com/sug'
#1.该请求是一个post(携带参数)
data={
    "kw":"dog"
}
data=urllib.parse.urlencode(data)

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

#自定义请求对象
request=urllib.request.Request(post_url,data=data.encode(),headers=headers)
#自定义的请求对象中的参数(data必须为bytes类型)
response=urllib.request.urlopen(request)
print(response.read().decode('unicode_escape'))

使用爬虫爬取Ajax的get请求


ajax的get请求:豆瓣网的分类排行榜案例分析

url='https://movie.douban.com/j/chart/top_list?'
start=input('enter the start:')
data={
    "type":'5',
    "interval_id":"100:90",
    "action":'',
    "start":start,
    "limit":1
}
data=urllib.parse.urlencode(data).encode()

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

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

response=urllib.request.urlopen(request)

print(response.read().decode())

使用爬虫爬取Ajax的post请求


ajax的post请求:
参考案例:http://www.kfc.com.cn/kfccda/index.aspx肯德基餐厅查询

url='http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword'
city=input('enter the city of you want to search:')
data={
    "cname":'',
    "keyword":city,
    "pageIndex":'1',
    "pageSize":"10",
    "pid":''
}
data=urllib.parse.urlencode(data).encode()
headers={
    "User-Agent":" Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36"
}
request=urllib.request.Request(url,data,headers)
response=urllib.request.urlopen(request)
print(response.read().decode())

综合练习:百度贴吧


需求:输入吧名,输入起始页码和结束页码,然后在当前文件夹中创建一个以吧名为名字的文件夹,里面是每一页html内容,文件名是吧名_pageNum.html

import ssl
import os
ssl._create_default_https_context = ssl._create_unverified_context

url='http://tieba.baidu.com/f?'
name=input('enter name:')
s_pageNum=int(input('enter start pageNum:'))
e_pageNum=int(input('enter end pageNum:'))
#创建一个存储html文件的文件夹
if not os.path.exists(name):
    os.mkdir(name)
for page in range(s_pageNum,e_pageNum+1):
    print('开始下载第%d页的内容'%page)
    data={
    "kw":name,
    "ie":'utf-8',
    "pn":(page-1)*50
}
    data=urllib.parse.urlencode(data)
    request=urllib.request.Request(url,data.encode())
    response=urllib.request.urlopen(request)
    #文件名称
    fileName=name+"_"+str(page)+'.html'
    filePath=name+'/'+fileName
    with open(filePath,'wb') as fp:
        fp.write(response.read())
    print('结束下载第%d页的内容'%page)

    '''
    enter name:周杰伦
    enter start pageNum:0
    enter end pageNum:3
    开始下载第0页的内容
    结束下载第0页的内容
    开始下载第1页的内容
    结束下载第1页的内容
    开始下载第2页的内容
    结束下载第2页的内容
    开始下载第3页的内容
    结束下载第3页的内容
    '''

上一篇:
下一篇:
0%