爬虫Day2 获得AJAX包响应

1 requests模块

python中原生的一款基于网络请求的模块,功能强大,简单便捷,效率极高

作用:模拟浏览器发送请求
使用:(requests模块的使用流程)

  • 指定url 网址
  • 发起请求
  • 获取响应数据
  • 持久化存储响应数据

首先要pip install requests

2 实战:爬取搜狗首页的页面数据

import requests


if __name__ == "__main__":
    # step1: 指定url
    url = "https://www.sogou.com/"
    # step2: 发起请求
    # get方法会返回一个响应对象
    responds = requests.get(url = url)
    # step3:响应数据的获取,字符串形式
    page_text = responds.text
    print(page_text)
    # step4: 持久化数据
    with open("D:/pachong/sogou.txt","w",encoding = "utf-8") as f:
        f.write(page_text)
    print("爬取数据结束")

3 实战:破解百度翻译
不再爬取整个页面了,只爬取翻译到的文本

UA检测&UA伪装:反爬与反反爬机制
在这里插入图片描述
观察网址变成了带dog的,读取这张页面的信息能找到翻译结果。
这里翻译的时候出现了局部刷新的情况,存在局部刷新的包,捕捉这些包里面发送刷新局部页面的包:
在这里插入图片描述
在XHR中逐个查看包中的post和请求信息(request)
在这里插入图片描述
对应的是一个post请求,且携带了参数,相应的数据是一个json数据

import requests
import json

if __name__ == "__main__":
    # 1.url指定
    post_url = "https://fanyi.baidu.com/sug"
    
    # 2.进行UA伪装
    headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36 Edg/88.0.705.74"}
    
    # 3.发送一个post请求,post可以携带数据
    data = {"kw":'dog'} # 没有参数也可以不加data
    response =  requests.post(url = post_url, data = data, headers = headers) # 返回一个相应
    
    print(response.text) #得到相应的字符串形式
    print(response.json()) #得到json字典
    
    dic_obj = response.json()
    
    #进行持久化存储,存储为json文件
    fp = open(r"D:\pachong\Day2\dog.json","w", encoding = "utf-8")
    json.dump(obj = dic_obj, fp = fp, ensure_ascii = False) # 中文不能使用ASCII编码的
    
    print("over!!!")

其中,post的参数可以从sug包里面看到应该是一个字典,形式如下:
在这里插入图片描述
进行UA伪装的时候,可以根据User-Agent伪装
在这里插入图片描述
在确认是json形式的数据之后,可以直接.json()获取一个字典对象,可以从Content-Type看出来
在这里插入图片描述
这样可以实现对任意单词的翻译:

import requests
import json

if __name__ == "__main__":
    # 1.url指定
    post_url = "https://fanyi.baidu.com/sug"
    
    # 2.进行UA伪装
    headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36 Edg/88.0.705.74"}
    
    # 3.发送一个post请求,post可以携带数据
    word = input("输入一个单词:")
    data = {"kw":word} # 没有参数也可以不加data
    response =  requests.post(url = post_url, data = data, headers = headers) # 返回一个相应
    
    # print(response.text) #得到相应的字符串形式
    # print(response.json()) #得到json字典
    
    dic_obj = response.json()
    
    
    print(dic_obj["data"][0]["v"])

在这里插入图片描述
只能对单个单词翻译!

4 实战:爬取豆瓣电影分类排行榜https://movie.douban.com/中的电影详情
点开豆瓣电影排行榜里的戏剧排行榜,打开局部请求的数据抓包情况,XHR包
在这里插入图片描述
随着网页上鼠标的下滑,页面会发送一个局部页面刷新的请求,就是新刷新出来的电影信息
在这里插入图片描述
那随着下滑,页面刷新会发现,多了一些局部信息请求的包,那这些
在这里插入图片描述
查看请求得到的响应的数据类型,还是json类型
在这里插入图片描述
打开响应,也可以看到响应的具体内容
在这里插入图片描述

import requests
import json
import pandas as pd

if __name__ == "__main__":
    # 1.url指定
    post_url = "https://movie.douban.com/j/chart/top_list"
    # 这里网址里面有参数,将参数单独拿出来
    param = {
        "type": "24",
        "interval_id" : "100:90",
        "action": " ",
        "start": "0", # 从排名60开始
        "limit": "20" # 一次请求取出20个
        }
      
    # 2 UA伪装
    headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36 Edg/88.0.705.74"}
    
    # 3 get请求
    response = requests.get(url = post_url, params = param, headers = headers)
    response = response.json()
    print(response)
    
    # 持久化数据
    fp = open("movie_rank.json","w",encoding = "utf-8")
    json.dump(response, fp, ensure_ascii = False)

在这里插入图片描述
如果要将爬取的数据变成表格按列存储起来,可以将json数据形式变成dataframe:

    # 持久化数据
    fp = open("movie_rank.json","w",encoding = "utf-8")
    json.dump(response, fp, ensure_ascii = False)
    
    dic = response[0]
    k = dic.keys()
    
    df = pd.DataFrame(response)
    oder = k
    file_path = pd.ExcelWriter('movie_rank.xlsx')  # 打开excel文件
    df = df[oder] # 按指定顺序排序df的各个属性
    # 替换空单元格
    df.fillna(' ', inplace=True)
    # 输出
    df.to_excel(file_path, encoding='utf-8', index=False,sheet_name="sheet1")
    file_path.save()

在这里插入图片描述

5 实战:爬取肯德基查询网站中指定地点的餐厅数量
在肯德基餐厅信息查询网址 http://www.kfc.com.cn/kfccda/storelist/index.aspx 里面
在搜索框中搜索“北京”,发现网址并没有变化,说明发送的请求是一个局部刷新请求,Ajax请求
在这里插入图片描述
对于Ajax请求都可以在XHR里面找到发送的请求包,根据这个包的样式,可以伪装成浏览器进行数据的爬取
在这里插入图片描述
那这里点了四页信息,抓取出来了四个包
可以查看param情况,和获取的response的数据类型
在这里插入图片描述
在这里插入图片描述
此处拿到的不再是json串了,拿到了一个的是一个text,注意

import requests
import json
import pandas as pd

if __name__ == "__main__":
    # 指定url
    post_url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword'
    # post_url = "http://www.kfc.com.cn/kfccda/storelist/index.aspx"
    params = {
        "cname":"", 
        "pid":"", 
        "keyword": "北京",
        "pageIndex": "7",
        "pageSize": "10"
    }
    
    # UA伪装
    headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36 Edg/88.0.705.74"}
    
    # 3 get请求
    response = requests.get(url = post_url, params = params, headers = headers)
    response = response.text
    print(response)
    
    # 持久化数据
    with open("D:/pachong/Day2/kfc_place.txt","w",encoding = "utf-8") as f:
        f.write(response)

在这里插入图片描述
这里的网址也是带参数的,要是不带参数,就要把参数传到params里面

在这里插入图片描述
如果要爬取每一页的信息下来,那么只需要加一个循环:

import requests
import json
import pandas as pd

t = ""

if __name__ == "__main__":
    # 指定url
    post_url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx'
    for ind in range(1,8):
        params = {
            "op":"keyword",
            "cname":"", 
            "pid":"", 
            "keyword": "北京",
            "pageIndex": str(ind),
            "pageSize": "10"
        }
        
        # UA伪装
        headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36 Edg/88.0.705.74"}
        
        # 3 get请求
        response = requests.get(url = post_url, params = params, headers = headers)
        response = response.text
        t = t + '\n' + response
        print(t)

t里面储存的就是每一页的信息,加一些匹配查找,就可以找出地址,后面还可以存储到excel表格里面

6 实战:爬取国家药品监督管理局中基于化妆品生产许可证的相关数据
根据网址提供的这些许可证书,爬取每个证书的详细信息,就是点进去之后的信息,网址发生变化,不是局部刷新,是根据超链接跳转了页面。
http://scxk.nmpa.gov.cn:81/xk/
在这里插入图片描述
首先看一下,对网址发请求,能不能得到每个许可证的超链接。

import requests
import json
import pandas as pd

if __name__ == "__main__":
    url = "http://scxk.nmpa.gov.cn:81/xk/"
    
    headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36 Edg/88.0.705.74"}
    
    response = requests.get(url, headers = headers)
    response = response.text
    
    with open("jiaojianju.html","w") as f:
        f.write(response)

将保存的html文件用网页打开看,发现是这样的
在这里插入图片描述
没有得到许可证目录,为什么会这样呢?
说明这组数据不是通过"http://scxk.nmpa.gov.cn:81/xk/"网址请求到的,是通过动态请求到的,这里查看AJAX请求的包,发现有这么一个包,响应里面有我们要的数据
在这里插入图片描述

通过对详细信息的网址观察,可以看出id值加到网址后面,就是每个证书详情页的url

import requests
import json
import pandas as pd

if __name__ == "__main__":
    url = "http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList"
    params = {
        'on': 'true',
        'page': '1',
        'pageSize': '15',
        'productName': '',
        'conditionType': '1',
        'applyname': '',
        'applysn':'',
        }
    
    headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36 Edg/88.0.705.74"}
    response = requests.post(url = url, data = params, headers = headers)
    response = response.json()
    
    print(response)

注意,写post的时候参数是data,而写get的时候,参数是params,这里用get请求不到数据,但是用post可以,不知道为啥(以后决定多用post)

详情页中的详情信息也是动态请求到的,AJAX请求
在这里插入图片描述
参数的id可以通过首页的信息得到,所有请求的url都是一样的,只有id不一样,所以通过对参数的调整完成详情页的AJAX请求

这里首先要把id从response中提取出来

import requests
import json
import pandas as pd

if __name__ == "__main__":
    url = "http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList"
    id_lis = []
    for y in range(10): # 爬一百页信息
        params = {
            'on': 'true',
            'page': str(y + 1),
            'pageSize': '15',
            'productName': '',
            'conditionType': '1',
            'applyname': '',
            'applysn':'',
            }
        
        headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36 Edg/88.0.705.74"}
        response = requests.post(url = url, data = params, headers = headers)
        response = response.json()
        
        # print(response)
        
        lis = response['list']
        for i in lis:
            id_lis.append(i['ID'])
    print(len(id_lis))
    

这里把10页的150条公司id列举出来了(本来循环了100页,但是到第50页的时候出错了,发现根本没有第50页,是真狗啊!!),根据id来查询详情页信息,并且把详细信息都存储在excel里面

    # 在url里面分别查询id参数时候的结果
    m_lis = []
    url_ = "http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById"
    for id in id_lis: 
        data = {"id": id}
        message = requests.post(url = url_ , data = data, headers = headers).json()
        m_lis.append(message)

    df = pd.DataFrame(m_lis) #DataFrame的参数必须是一个[{},{},{},{},...]类型的

    file_path = pd.ExcelWriter('yaojianju.xlsx')  # 打开excel文件
    
    # 替换空单元格
    df.fillna(' ', inplace=True)
    # 输出
    df.to_excel(file_path, encoding='utf-8', index=False,sheet_name="sheet1")
    file_path.save()

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值