scrapy案例教程

news2024/11/24 10:51:49

文章目录

  • 1 scrapy简介
  • 2 创建项目
  • 3 自定义初始化请求url
  • 4 定义item
  • 5 定义管道

1 scrapy简介

  • scrapy常用命令
    |命令 | 格式 |说明|
    |–|–|–|
    |startproject |scrapy startproject <项目名> |创建一个新项目|
    |genspider| scrapy genspider <爬虫文件名> <域名> |新建爬虫文件。
    |runspider| scrapy runspider <爬虫文件> |运行一个爬虫文件,不需要创建项目。
    |crawl| scrapy crawl |运行一个爬虫项目,必须要创建项目。
    |list |scrapy list |列出项目中所有爬虫文件。
    |view| scrapy view <url地址>| 从浏览器中打开 url 地址。
    |shell| csrapy shell <url地址> |命令行交互模式。
    |settings |scrapy settings |查看当前项目的配置信息。
  • 项目的目录树结构
    在这里插入图片描述
  • Scrapy 五大组件
名称作用说明
Engine(引擎)整个 Scrapy 框架的核心,主要负责数据和信号在不同模块间传递。
Scheduler(调度器)用来维护引擎发送过来的 request 请求队列。
Downloader(下载器)接收引擎发送过来的 request 请求,并生成请求的响应对象,将响应结果返回给引擎。
Spider(爬虫程序)处理引擎发送过来的 response, 主要用来解析、提取数据和获取需要跟进的二级URL,然后将这些数据交回给引擎。
Pipeline(项目管道)用实现数据存储,对引擎发送过来的数据进一步处理,比如存 MySQL 数据库等。
  • 两大中间件
  • 下载器中间件,位于引擎和下载器之间,主要用来包装 request 请求头,比如 UersAgent、Cookies 和代理 IP 等
  • 蜘蛛中间件,位于引擎与爬虫文件之间,它主要用来修改响应对象的属性。
  • 工作流程图
    在这里插入图片描述

2 创建项目

# 创建项目
scrapy startproject Medical
# 进入项目
cd Medical
# 创建爬虫文件
scrapy genspider medical www.baidu.com

3 自定义初始化请求url

import scrapy
import json
from scrapy.http import Response
from Medical.items import MedicalItem
from tqdm import tqdm

'''
具体的爬虫程序
'''


class MedicalSpider(scrapy.Spider):
    name = "medical"
    allowed_domains = ["beian.cfdi.org.cn"]

    # start_urls = ["https://beian.cfdi.org.cn/CTMDS/pub/PUB010100.do?method=handle05&_dt=20231101162330"]

    # 重写第一次请求处理函数
    def start_requests(self):
        start_url = 'https://www.baidu.com/CTMDS/pub/PUB010100.do?method=handle05&_dt=20231101162330'
        # 发送post请求
        data = {
            'pageSize': '1353',
            'curPage': '1',
        }
        yield scrapy.FormRequest(url=start_url, formdata=data, callback=self.parse)

    def parse(self, response):
        # 转换为json
        jsonRes = json.loads(response.body)
        # 查看响应状态码
        status = jsonRes['success']
        # 如果状态为True
        if status:
            # 获取数据
            dataList = jsonRes['data']
            # 调用详细方法,发起请求(循环发起)
            for row in tqdm(dataList,desc='爬取进度'):
                # 请求详情页url
                urlDetail = f"https://www.baidu.com/CTMDS/pub/PUB010100.do?method=handle04&compId={row['companyId']}"
                # 发起请求
                yield scrapy.Request(url=urlDetail, callback=self.parseDetail, meta={'row': row})

    def parseDetail(self, response: Response):
        # new 一个MedicalItem实例
        item = MedicalItem()

        # 获取上次请求的数据源
        row = response.meta['row']
        item['companyId'] = row['companyId']
        item['linkTel'] = row['linkTel']
        item['recordNo'] = row['recordNo']
        item['areaName'] = row['areaName']
        item['linkMan'] = row['linkMan']
        item['address'] = row['address']
        item['compName'] = row['compName']
        item['recordStatus'] = row['recordStatus']
        item['cancelRecordTime'] = row.get('cancelRecordTime', '')

        # 获取备案信息
        divTextList = response.xpath("//div[@class='col-md-8 textlabel']/text()").extract()
        # 去空白
        divtextList = [text.strip() for text in divTextList]
        compLevel = ''
        if len(divtextList) > 2:
            compLevel = divtextList[2]
        recordTime = ''
        if len(divtextList) > 5:
            recordTime = divtextList[6]
        item['compLevel'] = compLevel
        item['recordTime'] = recordTime

        # 获取其他机构地址
        divListOther = response.xpath("//div[@class='col-sm-8 textlabel']/text()").extract()
        # 去空白
        divtextListOther = [text.strip() for text in divListOther]
        otherOrgAdd = ','.join(divtextListOther)
        item['otherOrgAdd'] = otherOrgAdd

        # 获取备案专业和主要研究者信息
        trList = response.xpath("//table[@class='table table-striped']/tbody/tr")
        tdTextList = [tr.xpath("./td/text()").extract() for tr in trList]
        item['tdTextList'] = tdTextList

        # 返回item
        yield item

4 定义item

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html
import scrapy


class MedicalItem(scrapy.Item):
    # define the fields for your item here like:
    # 省份/地区
    areaName = scrapy.Field()
    # 公司id
    companyId = scrapy.Field()
    # 公司名称
    compName = scrapy.Field()
    # 公司等级
    compLevel = scrapy.Field()
    # 联系人
    linkMan = scrapy.Field()
    # 联系电话
    linkTel = scrapy.Field()
    # 备案号
    recordNo = scrapy.Field()
    # 地址
    address = scrapy.Field()
    # 备案状态
    recordStatus = scrapy.Field()
    # 取消备案时间
    cancelRecordTime = scrapy.Field()
    # 备案时间
    recordTime = scrapy.Field()

    # 其他机构地址
    otherOrgAdd = scrapy.Field()

    # 子表详情(矩阵)
    tdTextList = scrapy.Field()

5 定义管道

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html


# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
import pymysql

from Medical.items import MedicalItem


class MedicalPipeline:

    # 开始
    def open_spider(self, spider):
        # 初始化数据库
        self.db = pymysql.connect(
            host='localhost',
            port=3306,
            user='root',
            password='logicfeng',
            database='test2'
        )
        # 创建游标对象
        self.cursor = self.db.cursor()

    def process_item(self, item, spider):
        companyId = item['companyId']
        linkTel = item['linkTel']
        recordNo = item['recordNo']
        areaName = item['areaName']
        linkMan = item['linkMan']
        address = item['address']
        compName = item['compName']
        recordStatus = item['recordStatus']
        cancelRecordTime = item.get('cancelRecordTime', '')
        compLevel = item.get('compLevel', '')
        recordTime = item.get('recordTime', '')
        otherOrgAdd = item.get('otherOrgAdd', '')

        tdTextList = item['tdTextList']

        sql1 = "insert INTO medical_register(company_id,area_name,record_no,comp_name,address,link_man,link_tel,record_status,comp_level,record_time,cancel_record_time,other_org_add) "
        sql2 = f"values('{companyId}','{areaName}','{recordNo}','{compName}','{address}','{linkMan}','{linkTel}','{recordStatus}','{compLevel}','{recordTime}','{cancelRecordTime}','{otherOrgAdd}')"
        sql3 = sql1 + sql2
        # 执行sql
        self.cursor.execute(sql3)
        # 提交
        self.db.commit()

        for tdText in tdTextList:
            tdText.insert(0,companyId)
            # 插入数据库
            sql4 = "insert into medical_register_sub (company_id,professional_name,principal_investigator,job_title) values(%s,%s,%s,%s)"
            self.cursor.execute(sql4, tdText)
            # 提交到数据库
            self.db.commit()

        return item

    def close_spider(self, spider):
        self.cursor.close()
        self.db.close()
        print("关闭数据库!")

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

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

相关文章

【Linux】磁盘阵列,了解不同raid的特点

一、raid和阵列卡介绍 1、什么是磁盘阵列&#xff1a; 磁盘阵列是利用虚拟化存储技术把很多块独立的磁盘组合成一个容量巨大的磁盘组&#xff0c;利用个别磁盘提供数据所产生加成效果提升整个磁盘系统效能。利用这项技术&#xff0c;将数据切割成许多区段&#xff0c;分别存放…

CRM系统如何帮助无损检测设备企业发展?

得益于新兴行业的高速发展&#xff0c;近些年无损检测设备在国内市场得到了规模增长。通过搭建完整的CRM客户管理系统&#xff0c;打通营销、销售及服务各环节&#xff0c;进一步提高企业市场竞争力。CRM系统如何帮助无损检测设备企业发展&#xff1f; 无损检测设备企业无论在…

CSS 边框、轮廓线

一、CSS边框&#xff1a; CSS边框属性允许指定一个元素边框的样式和颜色。 1&#xff09;、边框样式&#xff1a;border-style属性用来定义边框的样式&#xff0c;border-style值&#xff1a; 2&#xff09;、边框宽度&#xff1a;border-width属性用于指定边框宽度。指定变宽…

TCP编程及基础知识

一、端口号 为了区分一台主机接收到的数据包应该转交给哪个进程来进行处理&#xff0c;使用端口号来区分TCP端口号与UDP端口号独立端口用两个字节来表示 2byte&#xff08;65535个&#xff09; 众所周知端口&#xff1a;1~1023&#xff08;1~255之间为众所周知端口&#xff…

软件测试/测试开发丨Python安装指南(macOS)

点此获取更多相关资料 下载 Python 解释器 下载地址: https://www.Python.org/downloads/macos 通过下载页面&#xff0c;可以在该页面上看到下载链接。 下载完成后会得到 Python-3.10.11-macos11.pkg安装文件 。 安装 Python 解释器 双击Python-3.10.11-macos11.pkg文件&a…

Vue3指令

Vue 指令&#xff08;Directives&#xff09;是 Vue.js 的一项核心功能&#xff0c;它们可以在 HTML 模板中以 v- 开头的特殊属性形式使用&#xff0c;用于将响应式数据绑定到 DOM 元素上或在 DOM 元素上进行一些操作。 Vue 指令是带有前缀 v- 的特殊 HTML 属性&#xff0c;它赋…

Linux操作系统中软件安装:用RPM包管理器安装软件步骤

安装软件的一般步骤如下&#xff1a; 1.打开终端&#xff0c;作为root用户或使用sudo命令获取管理员权限。 2.使用RPM命令进行软件包的安装。例如&#xff0c;使用“rpm -ivh 软件包名称.rpm”命令来安装软件包&#xff0c;其中“-i”表示安装&#xff0c;“-v”表示显示详细安…

【入门Flink】- 07Flink DataStream API【万字篇】

DataStream API 是 Flink 的核心层 API。一个 Flink 程序&#xff0c;其实就是对DataStream的各种转换。 代码基本上都由以下几部分构成&#xff1a; 执行环境&#xff08;Execution Environment&#xff09; 1&#xff09;创建执行环境StreamExecutionEnvironment StreamExe…

【启扬方案】基于RK3568核心板的激光打标机应用解决方案

激光打标机是一种利用激光技术进行标记和刻字的设备&#xff0c;作为激光技术应用的一个细分领域&#xff0c;是最早引入工业市场的一类激光装备&#xff0c;它采用激光束在工件表面进行刻印、打标&#xff0c;常用于工业生产中的物料标识、产品追溯、防伪标记等应用&#xff0…

centos7安装mysql-阿里云服务器

1.背景 2.安装 2.1.下载安装包 wget https://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm2.2.安装mysql rpm -ivh mysql57-community-release-el7-8.noarch.rpm 3.安装mysql服务 3.1.进入目录 首先进入cd /etc/yum.repos.d/目录 cd /etc/yum.repos.d/ 3.…

Netty 高性能原因之一 采用了高性能的NIO 模式

java IO简介 I/O 全称Input/Output&#xff0c;即输入/输出&#xff0c;通常指数据在内部存储器和外部存储器或其他周边设备之间的输入/输出。 涉及 I/O 的操作&#xff0c;不仅仅局限于硬件设备的读写&#xff0c;还要网络数据的传输。无论是从磁盘中读写文件&#xff0c;还…

【广州华锐互动】VR综合布线虚拟实验教学系统

随着科技的不断发展&#xff0c;虚拟现实&#xff08;VR&#xff09;技术已经逐渐渗透到各个领域&#xff0c;为人们的生活和工作带来了前所未有的便利。在建筑行业中&#xff0c;VR技术的应用也日益广泛&#xff0c;尤其是在综合布线方面。 广州华锐互动开发的VR综合布线虚拟实…

百度上线“文心一言”付费版本,AI聊天机器人市场竞争加剧

原创 | 文 BFT机器人 百度不愧是我国AI技术领域的先行者&#xff0c;每年致力于人工智能领域取得技术产品的突破和创新。据爆料称&#xff0c;百度的文心一言有突破了新境界&#xff0c;开创了文心大模型4.0会员版本。从线上的to C产品到试水商业化&#xff0c;百度都是争先走…

Python的requests库爬取商城优惠券

首先&#xff0c;我们需要了解要抓取的网页的结构和数据格式。在这个例子中&#xff0c;我们使用Python的requests库来发送HTTP请求&#xff0c;并使用BeautifulSoup库来解析HTML内容。 import requests from bs4 import BeautifulSoup然后&#xff0c;我们需要使用requests库的…

LeetCode | 160. 相交链表

LeetCode | 160. 相交链表 O链接 我们这里有两个问题&#xff0c;一是判断是否相交&#xff0c;二是找交点 思路一&#xff1a; 暴力求解 A链表所有节点依次取B链表找一遍&#xff08;时间复杂度是O(N^2)&#xff09; struct ListNode *getIntersectionNode(struct ListNod…

QT not in executable format:file truncated

今天在调研串口打印机的时候出现的&#xff0c;串口打印机有sdk&#xff0c;自己qt的编辑器用的 MinGW 64&#xff0c;编译出现次错误 出现这个错误&#xff0c;主要是sdk和编译器的版本位数不一致。 修改方法&#xff1a;把MinGW64 改为MinGW32&#xff0c;不过这个根据使用的…

为什么说制造企业需要部署MES管理系统

在数字化浪潮席卷的今天&#xff0c;每个企业都期望通过新技术、新模式来优化自身的运营。这其中&#xff0c;MES管理系统成为了不少企业的首选。那么&#xff0c;为何企业需要部署MES管理系统&#xff1f;又该如何搭建MES管理系统呢&#xff1f; 一、企业缘何钟情于MES系统&am…

LeetCode-20-有效的括号

1.我的暴力解法 class Solution {public boolean isValid(String s) {Stack<Character> stknew Stack<Character>();int i0;//奇数直接不可能是匹配的if(s.length()%2!0)return false;for (;i<s.length();i){if(s.charAt(i)(){stk.push(();}else if(s.charAt(i…

NVM安装node后提示没有对应npm包(即:无法将“npm”项识别为 cmdlet、函数、脚本文件)

背景 windows11 node版本降低到v12.22.12后&#xff0c;执行&#xff1a;nvm -v npm -v npm : 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;如果 包括路径&#xff0c;请确保路径正确&#xff0c;然后再试一次。 所在位置 …

【bug-maven】(一)java: 错误: 不支持发行版本 5 (二):java: 错误: 无效的源发行版:15

【bug-maven】&#xff08;一&#xff09;java: 错误: 不支持发行版本 5 &#xff08;二&#xff09;&#xff1a;java: 错误: 无效的源发行版&#xff1a;15 &#xff08;一&#xff09;java: 错误: 不支持发行版本 5 报错截图&#xff1a; 出错原因&#xff1a; 打开Projec…