Implementación del rastreador de solicitudes POST basado en el marco Scrapy
Prefacio
Este artículo presenta cómo implementar un rastreador de solicitudes POST basado en el marco Scrapy y lo demuestra tomando como ejemplo la captura de información de la tienda KFC en una ciudad específica.
texto
1. Cómo maneja el marco Scrapy las solicitudes POST
El marco Scrapy proporciona el método FormRequest() para enviar solicitudes POST;
el método FormRequest() tiene más parámetros de datos de formulario que el método Request(), acepta un diccionario o una tupla iterable que contiene datos de formulario y los convierte en el cuerpo de la solicitud. .
Solicitud POST: yield scrapy.FormRequest(url=post_url,formdata={},meta={},callback=...)
Nota: Cuando utilice el método FormRequest() para enviar una solicitud POST, debe anular el método start_requests().
2. El marco Scrapy maneja casos de solicitudes POST
-
Requisitos del proyecto: capturar información de las tiendas KFC en ciudades específicas. La terminal le indica que ingrese la ciudad: xx para capturar todos los datos de la tienda KFC en la ciudad xx.
-
Datos requeridos: número de tienda, nombre de la tienda, dirección de la tienda, ciudad, provincia
-
Dirección URL: http://www.kfc.com.cn/kfccda/storelist/index.aspx
-
Dirección URL de solicitud POST: http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname
-
Análisis de captura de paquetes F12: encuentre los datos que deben rastrearse, obtenga información de la tienda y obtenga el número total de tiendas
-
Obtener formulario: Obtener datos del formulario
-
Cree un proyecto Scrapy: escriba el archivo items.py
import scrapy class KfcspiderItem(scrapy.Item): # 门店编号 rownum = scrapy.Field() # 门店名称 storeName = scrapy.Field() # 门店地址 addressDetail = scrapy.Field() # 所属城市 cityName = scrapy.Field() # 所属省份 provinceName = scrapy.Field()
-
Escribir archivos de rastreo
import scrapy import json from ..items import KfcspiderItem class KfcSpider(scrapy.Spider): name = "kfc" allowed_domains = ["www.kfc.com.cn"] post_url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname' city_name = input("请输入城市名称:") # start_urls = ["http://www.kfc.com.cn/"] def start_requests(self): """ 重写start_requests()方法,获取某个城市的KFC门店总数量 :return: """ formdata = { "cname": self.city_name, "pid": "", "pageIndex": '1', "pageSize": '10' } yield scrapy.FormRequest(url=self.post_url, formdata=formdata, callback=self.get_total,dont_filter=True) def parse(self, response): """ 解析提取具体的门店数据 :param response: :return: """ html=json.loads(response.text) for one_shop_dict in html["Table1"]: item=KfcspiderItem() item["rownum"]=one_shop_dict['rownum'] item["storeName"]=one_shop_dict['storeName'] item["addressDetail"]=one_shop_dict['addressDetail'] item["cityName"]=one_shop_dict['cityName'] item["provinceName"]=one_shop_dict['provinceName'] #一个完整的门店数据提取完成,交给数据管道 yield item def get_total(self, response): """ 获取总页数,并交给调度器入队列 :param response: :return: """ html = json.loads(response.text) count = html['Table'][0]['rowcount'] total_page = count // 10 if count % 10 == 0 else count // 10 + 1 # 将所有页的url地址交给调度器入队列 for page in range(1, total_page + 1): formdata = { "cname": self.city_name, "pid": "", "pageIndex": str(page), "pageSize": '10' } # 交给调度器入队列 yield scrapy.FormRequest(url=self.post_url, formdata=formdata, callback=self.parse)
-
Escriba el archivo de configuración:
BOT_NAME = "KFCSpider" SPIDER_MODULES = ["KFCSpider.spiders"] NEWSPIDER_MODULE = "KFCSpider.spiders" # Obey robots.txt rules ROBOTSTXT_OBEY = False # See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay # See also autothrottle settings and docs DOWNLOAD_DELAY = 1 # Override the default request headers: DEFAULT_REQUEST_HEADERS = { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en", "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko)" } # 设置日志级别:DEBUG < INFO < WARNING < ERROR < CARITICAL LOG_LEVEL = 'INFO' # 保存日志文件 LOG_FILE = 'KFC.log' # Configure item pipelines # See https://docs.scrapy.org/en/latest/topics/item-pipeline.html ITEM_PIPELINES = { "KFCSpider.pipelines.KfcspiderPipeline": 300, } # Set settings whose default value is deprecated to a future-proof value REQUEST_FINGERPRINTER_IMPLEMENTATION = "2.7" TWISTED_REACTOR = "twisted.internet.asyncioreactor.AsyncioSelectorReactor" FEED_EXPORT_ENCODING = "utf-8"
-
Imprima elementos directamente en el archivo de canalización
-
Cree un archivo run.py para ejecutar el rastreador:
from scrapy import cmdline cmdline.execute("scrapy crawl kfc".split())
-
resultado de ejecución