33. 实战:实现某网站店铺信息的查询与批量抓取(附源码)

news2024/9/21 10:43:01

目录

前言

目的

思路

代码实现

1. 请求URL,获取源代码

2. 解析源代码,获取数据

3. 完善保存数据的函数save_data

4. 理清main函数逻辑,循环传递每一页有效信息的参数

完整代码

运行效果

总结


前言

近日,我们每周四都能刷到一堆“疯狂星期四”的梗图或者消息,那么如果真的Vivo50,我们该去哪里消费呢?假设我们来到一个新的城市,或者想知道我们爆了50金币网友所在的城市到底有没有相关店铺该怎么办?

那么我们就可以来进行一个小小的爬虫,一次编程,方便后面的每一次查询。


目的

1. 实现输入任意关键词查询店铺

2. 将所有店铺信息输出到控制台,自行选择是否保存到本地

3. 要求是封装好的结果,将各个功能分离


思路

1. 请求URL,获取源代码

2. 解析源代码,获取数据

3. 完善逻辑


代码实现

1. 请求URL,获取源代码

首先访问请求店铺信息页面(URL不便展示,放在评论区了),发现我们查询以后页面URL是不变的,那么我们就很自然的想到是一个动态请求。

那么很熟悉,打开抓包工具,输入任意关键词,查询店铺,发现拿到了一个json:

打开标头项,可以拿到URL与请求方式,打开负载,可以拿到请求所需的参数,打开预览,可以发现里面包含了我们想要的数据。

import requests
import json
import csv

# 全局变量URL与UA
url = '见评论区'
UA = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.1518.61"
}


# 请求URL,获取源代码
def request_url(link, headers, params):
    resp = requests.post(url=link, headers=headers, params=params)
    resp.encoding = 'utf-8'
    return resp.text

2. 解析源代码,获取数据

解析源代码需要两个变量:请求结果与存储请求。参数一很好理解,它就是我们要解析的数据,参数二是我们自定义的是否存储到本地文件的一个变量,当它为y时选择调用save_data函数将信息保存到本地csv文件,为n时不调用,仅在控制台输出

# 解析请求到的信息
def parse_data(resp, save):
    data = json.loads(resp)
    if len(data["Table1"]) == 0:
        return True
    # 如果Table1包含信息,那就遍历拿出每一条
    for store_dict in data["Table1"]:
        print(store_dict)
        if save == 'y':
            save_data(store_dict)

3. 完善保存数据的函数save_data

# 保存店铺信息到本地
def save_data(store_dict):
    with open('2_KFC_Store_List.csv', mode='a+', newline='', encoding='utf-8') as f:
        csvwriter = csv.writer(f)
        storeName = store_dict['storeName']
        addressDetail = store_dict['addressDetail']
        pro = store_dict['pro']
        provinceName = store_dict['provinceName']
        cityName = store_dict['cityName']
        csvwriter.writerow([storeName, addressDetail, pro, provinceName, cityName])

4. 理清main函数逻辑,循环传递每一页有效信息的参数

def main():
    pageIndex = 1
    store_name = input("欢迎使用KFC店铺查询系统!请输入您想要查询店铺的关键词\n")
    save_query = input("是否保存店铺信息到本地?(y/n)\n")
    if save_query == 'n':
        print("正在处理信息...店铺信息将打印到控制台...")
    if save_query == 'y':
        print("正在处理信息...店铺信息将打印到控制台并保存到本地文件'2_KFC_Store_List.csv'...")
    while True:
        data_dict = {
            "cname": "",
            "pid": "",
            "keyword": store_name,
            "pageIndex": pageIndex,
            "pageSize": 10
        }
        resp = request_url(url, UA, data_dict)
        if parse_data(resp, save_query):
            break
        else:
            pageIndex += 1


if __name__ == '__main__':
    main()

如上述代码, 当解析数据函数拿到的店铺信息为空时会返回True,当True时就结束循环,否则页码+1继续翻页

同时也能注意到主函数运行前要先输入两个参数,一个是params中必需的查询关键词keyword,另一个是是否保存信息到本地的一个参数,为y或n。


完整代码

import requests
import json
import csv

# 全局变量URL与UA
url = '见评论区'
UA = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.1518.61"
}


# 请求URL,获取源代码
def request_url(link, headers, params):
    resp = requests.post(url=link, headers=headers, params=params)
    resp.encoding = 'utf-8'
    return resp.text


# 解析请求到的信息
def parse_data(resp, save):
    data = json.loads(resp)
    if len(data["Table1"]) == 0:
        return True
    # 如果Table1包含信息,那就遍历拿出每一条
    for store_dict in data["Table1"]:
        print(store_dict)
        if save == 'y':
            save_data(store_dict)


# 保存店铺信息到本地
def save_data(store_dict):
    with open('2_KFC_Store_List.csv', mode='a+', newline='', encoding='utf-8') as f:
        csvwriter = csv.writer(f)
        storeName = store_dict['storeName']
        addressDetail = store_dict['addressDetail']
        pro = store_dict['pro']
        provinceName = store_dict['provinceName']
        cityName = store_dict['cityName']
        csvwriter.writerow([storeName, addressDetail, pro, provinceName, cityName])


def main():
    pageIndex = 1
    store_name = input("欢迎使用KFC店铺查询系统!请输入您想要查询店铺的关键词\n")
    save_query = input("是否保存店铺信息到本地?(y/n)\n")
    if save_query == 'n':
        print("正在处理信息...店铺信息将打印到控制台...")
    if save_query == 'y':
        print("正在处理信息...店铺信息将打印到控制台并保存到本地文件'2_KFC_Store_List.csv'...")
    while True:
        data_dict = {
            "cname": "",
            "pid": "",
            "keyword": store_name,
            "pageIndex": pageIndex,
            "pageSize": 10
        }
        resp = request_url(url, UA, data_dict)
        if parse_data(resp, save_query):
            break
        else:
            pageIndex += 1


if __name__ == '__main__':
    main()

运行效果

 


总结

本节我们练习了抓取指定关键词的某快餐所有店铺信息,较为综合,主要学习思路,可以举一反三。

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

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

相关文章

ESP-C3入门5. 使用通用计时器

ESP-C3入门5. 使用通用计时器一、 简介二、使用步骤三、操作函数1. 基本操作(1)定时器实例 gptimer_handle_t (2) 定时器配置结构体 gptimer_config_t(3) 定时器初始化 timer_init()(3&#xff…

探索 Vue.js 中引用的力量:访问和操作 DOM 元素”

0.简介 Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架。它由 Evan You 于 2014 年创建,此后作为构建 Web 应用程序的工具越来越受欢迎。 Vue 的核心特性包括: 反应式数据绑定:Vue 使用反应式系统来跟踪对数据模型的更改并自动更新…

22年部署之docker学习

以下记录的是,我在学习中的一些学习笔记,这篇笔记是自己学习的学习大杂烩,主要用于记录,方便查找https://hub.docker.com/ 镜像中心Docker 常用命令: docker 运行相关运行: service docker start停止&#…

【三年面试五年模拟】算法工程师的独孤九剑秘籍(前十二式汇总篇)V1版

写在前面 【三年面试五年模拟】栏目专注于分享AI行业中实习/校招/社招维度的必备面积知识点与面试方法,并向着更实战,更真实,更从容的方向不断优化迭代。也欢迎大家提出宝贵的意见或优化ideas,一起交流学习💪 大家好&a…

ABB机器人系统输入输出信号System Input和Output详解(一)

ABB机器人系统输入输出信号System Input和Output详解 System Input类型: 输入I/O信号可指定具体的系统输入项,比如Start或Motors on。该输入项会在不使用FlexPendant示教器或其它硬件装置的情况下触发一项交由系统处理的系统行动。 可以用一个PLC来触发相应的系统输入项。 注…

Node.js教程笔记(三)express

学习目标 能够使用express.static()快速托管静态资源 能够使用express路由精简项目结构 能够使用常见的express中间件 能够使用express创建API接口 能够在express中启用cors跨域资源共享 目录 初识Express Express路由 Express中间件 使用Express写接口 1、初识Expres…

【通信原理(含matlab程序)】实验三 数字基带信号及其频谱特性

💥💥💞💞欢迎来到本博客❤️❤️💥💥 本人持续分享更多关于电子通信专业内容以及嵌入式和单片机的知识,如果大家喜欢,别忘点个赞加个关注哦,让我们一起共同进步~ &#x…

Android OpenCV(二)主体识别 位置检测

前言 工作中遇到需要通过OpenCV找到图片主体体积占图片百分比的比例,这里做一个问题解决思路的记录。该方面新手小白,有不对的地方可以评论指出哈 。 重要API Sobel算法 Sobel 计算参考文章 索贝尔算子是计算机视觉领域的一种重要处理方法。 主要用于…

内网传输——解决物联网信息安全和隐私保护问题

与普通电脑系统不同,物联网建立在嵌入式系统的基础之上,其通信协议因设备和应用程序而异。目前还没有一个统一的中央系统来构建安全措施,那么,在企业物联网实际应用中,如何保证信息安全?物联网生态系统的安…

OpenHarmony社区运营报告(2022年12月)

本月快讯• 本月新增22款产品通过兼容性测评,累计220款产品通过兼容性测评。• 12月28日,OpenAtom OpenHarmony(以下简称“OpenHarmony”)凭借其创新的技术特性和开源生态建设成果,荣膺“InfoQ 2022年度十大开源新锐项…

Redis实现用户签到 | 黑马点评

目录 一、BitMap用法 1、介绍 2、用法 3、练习 二、签到功能 1、需求 2、代码实现 三、签到统计 1、分析 2、接口实现 一、BitMap用法 1、介绍 我们完全可以通过数据库签到表来实现签到功能,但是假如我们的用户达到千万,每年平均签到10次&am…

基于微信小程序的网络安全科普系统小程序

文末联系获取源码 开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7/8.0 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包:Maven3.3.…

设计模式之简单工厂

现在有一个这样的需求:控制台输入俩个数,并输入运算符,计算并输出结果。上述需求乍一看,特别像一个小型的计算器,记得初学Java时,实现过。 实现一: 创建计算器类,控制台输入俩个数…

windows 10 本地配置Oracle19+用navicat连接

文章目录0.背景环境0.背景知识1.卸载旧版本、安装 oracle 192.配置3.用 Navicat 连接3.1 下载instantclient193.2 配置dll使能连接高版本oracle3.3 配置连接4. 相关操作命令5.本地命令行登录orclpdb下的用户0.背景环境 本机已安装oracle12和Navicat15,需要先彻底卸载…

【docker】基础知识梳理与使用

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 docker基础知识的梳理与使用 1. docker的理解 Registry(仓库):是一个集中存储与分发镜像的服务。最常用的Registry是…

油井远程监控解决方案

1.项目背景 油田生产过程中,由于井筒内存在着不同程度的缺陷,会产生各种问题。而油井开采设备的连续稳定运行是保证石油开采的首要条件,但是由于油田地域广阔,油井分布广泛,没有规则性的油井工作状况的监测和控制&…

Acwing4655. 重新排序(差分模板题)

给定一个数组 A 和一些查询 Li,Ri,求数组中第 Li 至第 Ri 个元素之和。 小蓝觉得这个问题很无聊,于是他想重新排列一下数组,使得最终每个查询结果的和尽可能地大。 小蓝想知道相比原数组,所有查询结果的总和最多可以增加多少? …

【树】二叉树的非递归遍历

非递归的遍历需要使用栈保存当前不输出的结点,并且三种遍历顺序步骤有所不同。中序遍历1.查看其当前结点是否为空:若非空则将当前结点入栈,指针指向其左孩子;若当前结点为空,说明上一个入栈的结点没有左孩子&#xff0…

vite+vue3+elementPlus搭建项目

创建基础框架 方式一: 创建命令 npm create vitelatest or yarn create vite 注意:这里可能会出现一个坑,注意你的node版本(node版本过低就会报错) 创建成功 创建成功后运行以下命令即可 yarn yarn dev 这种创建方…

C技能树-判断语句

三个数从小到大排序并输出 任意输入3个整数&#xff0c;使用if语句对这3个整数由小到大进行升序排序。请判断下面哪一项无法实现该功能。 #include <stdio.h>/* 交换x和y */ void swap(int* x, int* y) {int temp *x;*x *y;*y temp; }int main(int argc, char** arg…