Scrapy框架进行数据采集详细实现

news2024/9/21 16:45:58

摘要

本项目是python课程的课程项目,在简要学习完python和爬虫相关的Scrapy框架后,基于这两者的运用最终完成了对于北京链家网站房页面的信息进行爬取,并将爬取的数据存放于excel之中,使用excel或者wps进行查看。

1 引言

1.1背景

在本学期的python课程中,通过网课粗略的掌握了python的基础知识之后,老师提出通过运用python的模块进行附加的学习,于是我选择了Scrapy框架的学习,由此为基础对于链家网站的信息进行了爬取数据的操作,并将爬取的数据保存。

1.2意义

这个项目提高了我的python编程水平,使得我对于爬虫技术的了解更加深入,粗略掌握了如何使用Scrapy框架进行爬虫操作,懂得了python的附加模块的强大之处,也激发了继续学习编程的兴趣。

1.3相关研究

Scrapy 是用 Python 实现的一个为了爬取网站数据、提取结构性数据而编写的应用框架。Scrapy 常应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。通常我们可以很简单的通过 Scrapy 框架实现一个爬虫,抓取指定网站的内容或图片。之前在基础学习的时候使用的是Python的request模块也能对网站页面的数据进行爬取,但是request属于页面级爬虫,重点在于页面下载,并发考虑不足,性能较差。

2  系统结构

1

该项目是基于Scrapy框架来进行的,因此整体的框架如图1所示。由于Scrapy本身封装了大量的内容操作使得代码编写者可以简化自己的代码量。由于大量的封装,在本次项目中只需要修改SPIDERS模块和ITEM PIPELINES模块。

SPIDERS模块是该项目的python模块。在此放入代码。它解析Downloader返回的响应(Response)产生爬取项(scraped item)。产生额外的爬取请求(Request)

ITEM PIPELINES模块,以流水线的方式处理Spider产生的爬取项。由一组操作顺序组成,类似流水线,每个操作都是一个item Pipeline类型。它的操作包括:清理、检验、和查重爬取的HTML数据、将数据存储到数据库或者其他文件中

Engine(引擎):负责Spider、ItemPipeline、Downloader、Scheduler中间的通讯,信号、数据传递等。

Scheduler(调度器):它负责接受引擎发送过来的Request请求,并按照一定的方式进行整理排列,入队,当引擎需要时,交还给引擎。

Downloader(下载器):负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spider来处理。

Downloader Middlewares(下载中间件):你可以当作是一个可以自定义扩展下载功能的组件。

Spider Middlewares(Spider中间件):你可以理解为是一个可以自定扩展和操作引擎和Spider中间通信的功能组件(比如进入Spider的Responses;和从Spider出去的Requests)

简单地理解就是,有要爬去的任务在Scheduler(调度器)排队等待爬取,然后requests请求Internet,spider在Downloader(下载器)里得到响应,最后通过管道保存到相应位置。

3实现代码

3.1建立工程和Spider模板

scrapy startproject lianjia_bj

建立名为lianjia_bj的工程

scrapy genspider bj lianjia.com

创建一个名为bj的爬虫,搜索的域名范围是lianjia.com

3.2编写Spider

这一部分主要是配置bj.py文件,修改对返回页面的处理,修改对新增URL爬取请求的处理。首先通过对https://bj.lianjia.com/loupan/pg{}网页进行信息提取,获取每个房的房源信息,再通过yield关键字不断提取标签中的信息。这里信息的提取这里使用的是xpath。

通过览器查看网页源代码可以详细去查view-source:https://bj.lianjia.com/loupan/pg1/的代码,然后可以发现li"标签后面紧跟的标签中的属性值就是每个房源的详情信息。使用xpath进行一一提取即可。

代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import scrapy
import time
from lianjia_bj.items import LianjiaBjItem
import random

class BjSpider(scrapy.Spider):
    name = 'bj'
    # allowed_domains = ['bj.lianjia.com']  # 爬取的域,防止跳转到其他链接
    start_urls = ['https://bj.fang.lianjia.com/loupan/pg1']  # 目标URL

    def parse(self, response):
        divs = response.xpath('/html/body/div[3]/ul[2]/li')
        for div in divs:
            item = LianjiaBjItem()
            item['title'] = div.xpath('./div/div[1]/a/text()')[0].extract()
            item['area'] = div.xpath('./div/div[3]/span/text()')[0].extract()
            item['house_leixing'] = div.xpath('./div/div[1]/span[1]/text()')[0].extract()
            item['house_xiaoshou'] = div.xpath('./div/div[1]/span[2]/text()')[0].extract()
            item['house_qu'] = div.xpath('./div/div[2]/span[1]/text()')[0].extract()
            item['house_xiangzhen'] = div.xpath('./div/div[2]/span[2]/text()')[0].extract()
            item['house_dizhi'] = div.xpath('./div/div[2]/a/text()')[0].extract()
            house_huxing1=div.xpath('./div/a/span/text()')
            house_maidian1 = div.xpath('./div/div[5]/span/text()')
            item['money_danjia'] = div.xpath('./div/div[6]/div[1]/span[1]/text()')[0].extract()
            item['money_zongjia'] = div.xpath('./div/div[6]/div[2]/text()')[0].extract()
            if len(house_huxing1)==1:
                item['house_huxing']=house_huxing1[0].extract()
            elif len(house_huxing1)==2:
                item['house_huxing'] = house_huxing1[0].extract()+'/'+house_huxing1[1].extract()
            elif len(house_huxing1) == 3:
                item['house_huxing'] = house_huxing1[0].extract() + '/'+house_huxing1[1].extract()+ '/'+house_huxing1[2].extract()
            elif len(house_huxing1) == 4:
                item['house_huxing'] = house_huxing1[0].extract() + '/'+house_huxing1[1].extract()+ '/'+house_huxing1[2].extract()+ '/'+house_huxing1[3].extract()
            else:
                item['house_huxing'] = house_huxing1[0].extract()
            if len(house_maidian1)==1:
                item['house_maidian']=house_maidian1[0].extract()
            elif len(house_maidian1)==2:
                item['house_maidian'] = house_maidian1[0].extract()+'/'+house_maidian1[1].extract()
            elif len(house_maidian1) == 3:
                item['house_maidian'] = house_maidian1[0].extract() + '/'+house_maidian1[1].extract()+ '/'+house_maidian1[2].extract()
            elif len(house_maidian1) == 4:
                item['house_maidian'] = house_maidian1[0].extract() + '/'+house_maidian1[1].extract()+ '/'+house_maidian1[2].extract()+ '/'+house_maidian1[3].extract()
            else:
                item['house_maidian'] = house_maidian1[0].extract()
            # print(title,area,house_dizhi,house_huxing,house_leixing,house_maidian,house_qu,house_xiangzhen,house_xiaoshou,money_danjia,money_zongjia)
            print(house_huxing1)

            time.sleep(1)
            yield item
        next_url = 'https://bj.fang.lianjia.com/loupan/pg{page}'
        # time.sleep(random(1,3))
        for page in list(range(2, 5)):  # 控制页数
            yield scrapy.Request(next_url.format(page=page),callback=self.parse)  # 回调

3.2编写Pipelines

这一部分主要是配置pipelines.py文件,主要定义对LianjiaBjPipeline_csv

处理类以及通过setting.py文件配置ITEM_PIPLINES选项。这里主要是将爬取的数据放入excel之中,首先建立表头,最后再将爬取的数据进行插入。

代码如下:

from openpyxl import Workbook

class LianjiaBjPipeline_csv(object):  # Excel
    def __init__(self):
        self.wb = Workbook()
        self.ws = self.wb.active
        self.ws.append(['title','area','house_dizhi','house_huxing','house_leixing','house_maidian','house_qu','house_xiangzhen','house_xiaoshou','money_danjia','money_zongjia'])

    def process_item(self, item, spider):
        line = [item['title'],item['area'], item['house_dizhi'], item['house_huxing'],item['house_leixing'],item['house_maidian'], item['house_qu'], item['house_xiangzhen'],item['house_xiaoshou'],item['money_danjia'], item['money_zongjia']]
        self.ws.append(line)
        self.wb.save('bjxinfang.xlsx')
        return item

    def close_spider(self, spider):
        self.wb.save('bjxinfang.xlsx')

这里是setting.py要修改的部分,让框架能够找到我们在piplines中新建的类

ITEM_PIPELINES = {
   'lianjia_bj.pipelines.LianjiaBjPipeline_csv': 100,
}

4 爬虫实现

新建一个scrapy框架的运行程序main.py,这样就可以直接运行,不用在通过cmd命令运行了,方便快捷。代码如下:

from scrapy import cmdline

cmdline.execute ('scrapy crawl bj'.split())

4.1运行爬虫代码

最终结果:

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

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

相关文章

论文分享 | Fuzz4All: 基于大语言模型的通用模糊测试

大语言模型是当前最受关注的研究热点,基于其生成和理解能力,对现有领域在提升性能和效果上做更多尝试。分享一篇发表于2024年ICSE会议的论文Fuzz4All,它组合多个大语言模型以非常轻量且黑盒的方式,实现了一种跨语言和软件的通用模…

【数学分析笔记】第1章第2节:映射与函数(2)

1. 集合与映射 1.12 函数(实函数) 函数是映射的一种特殊情况, f : X ⟶ Y f:\textbf{X}\longrightarrow \textbf{Y} f:X⟶Y x ⟼ y f ( x ) x\longmapsto yf(x) x⟼yf(x) 如果 X ⊂ R , Y R \textbf{X}\subset\mathbb{R},\textbf{Y}\ma…

OpenCV的Hello World

按照前文的步骤,我们已经在Windows机器上把OpenCV源代码编译成了DLL。接下来的问题自然是,我们怎么在自己的项目中使用OpenCV?我们将从零开始编写第一个OpenCV “Hello World”程序。通过本文的练习,大家将掌握: 在自…

你真的懂什么是串口吗?

你真的懂什么是串口吗? 文章目录 你真的懂什么是串口吗?问题什么是串口概念4种电平及其特性串口与电脑USB口通信 通讯分类常见的串行通信接口通信方式分类串行通信并行通信 传输方向分类同步方式分类PS:波特率和比特率 RS232 和 RS485RS232 引…

Django 中显示图片

在 Django 中显示图片的基本步骤包括:配置静态文件和媒体文件的处理、上传图片、以及在模板中显示图片。以下是详细步骤: 问题背景: 我在学习 Django 并在构建一个简单的网站,我尝试使用模板语言添加一些图片,但显示的…

升级阿里云linux服务器上的php版本

查看已安装的php软件包 [rootiZbp13pl2v34qj0thwq9aiZ ~]# rpm -qa|grep php php74-php-common-7.4.26-1.el7.remi.x86_64 oniguruma5php-6.9.7.1-1.el7.remi.x86_64 php74-php-gd-7.4.26-1.el7.remi.x86_64 php74-php-opcache-7.4.26-1.el7.remi.x86_64 php74-php-json-7.4.2…

阿里云Elasticsearch 企业级AI搜索方案发布

在AI技术日新月异的今天,尤其是大语言模型的兴起,企业智能化场景的解决方案正经历一场前所未有的革新。然而,大模型在实际应用中面临的挑战不容小觑,如何高效、精准地服务于企业的个性化需求成为关键。阿里云搜索产品团队通过阿里…

QT文件的操作

QT文件的操作 学习QT的文件操作类:Qfile、QTextStream。利用QtCreator工具实现文件的操作过程。通过文件读取样式表文件,动态的改变控件的外观。QFile提供了操作文件的常用功能。是一种IO设备,可以用来读写文本文件和二进制文件,也可以用来读写QT的资源文件。QFile类可以单…

仓库与文件的提交/修改/删除

目录 1. 创建仓库 ​编辑​编辑 2. 界面解释 3. 再创建仓库 4. 移除仓库 5. 本地添加文件到仓库 ​编辑​编辑 6. 比对,提交 7. 修改,提交 8. 查询版本号 9. 删除文件 git 是分布式版本控制工具,需要将中央服务器克隆到本地&#…

【Spark集群部署系列一】Spark local模式介绍和搭建以及使用(内含Linux安装Anaconda)

简介 注意: 在部署spark集群前,请部署好Hadoop集群,jdk8【当然Hadoop集群需要运行在jdk上】,需要注意hadoop,spark的版本,考虑兼容问题。比如hadoop3.0以上的才兼容spark3.0以上的。 下面是Hadoop集群部署…

wps怎么找回未保存的文件?分享三个文件恢复方法

在编辑WPS文档时,偶尔会遇到未保存就意外关闭的情况,这不仅令人沮丧,还可能导致重要信息的丢失。但幸运的是,WPS提供了多种途径来帮助用户找回这些未保存的宝贵文件。从利用WPS的自动备份与恢复功能,到检查最近文档列表…

docker安装es8和kibana

es8、kibana安装、ik分词器使用 1 拉取镜像2 创建网络3 安装ES3.1 启动临时的ES3.2 运行es3.3 修改用户密码 4 安装kibana4.1 启动临时的kibana4.2 修改配置文件4.3 重启kibana4.4 调用5601端口(我映射的是8082) 5 安装ik分词器(离线安装&…

聚众力·链未来 | 2024 FISCO BCOS认证合作伙伴开放申请

“独行虽速,众行方远”,一个充满蓬勃生命力的开源社区需要众多伙伴结伴同行,彼此支持,方能行远。开源7年来,FISCO BCOS开源社区始终秉持开放、连接的开源精神,与业界伙伴共同推动国产开源联盟链生态可持续性…

江理工文档管理系统的设计与实现

TOC springboot148江理工文档管理系统的设计与实现 绪论** 1.1 研究背景 在这个推荐个性化的时代,采用新技术开发一个文档系统来分享和展示内容是一个永恒不变的需求。本次设计的文档管理系统有管理员和用户两个角色。管理员功能有论坛管理,公告管理…

【网络协议】网络劫持 - ARP/DNS欺骗篇

前言 网络劫持是一种网络攻击技术,攻击者通过拦截、篡改或重定向数据流量,控制用户的网络通信路径,干扰正常的网络服务。其方式可能包括DNS劫持、ARP欺骗和HTTP劫持等。通过这些手段,攻击者可以窃取敏感信息如个人身份数据和财务信…

3 第一个 C 程序、程序编译过程、注释、printf 基本使用、代码块风格

目录 1 第一个 C 程序 1.1 需求说明 1.2 开发步骤 1.3 使用终端运行程序 1.4 程序代码分析 2 C 程序运行机制流程 2.1 编写 2.2 预处理 2.3 编译 2.4 汇编 2.5 链接 2.6 运行 2.7 gcc 步骤指令 3 C 程序开发注意事项 4 注释 4.1 什么是注释 4.2 注释的作用 4…

Java面试八股之什么是AMQP协议

什么是AMQP协议 AMQP(Advanced Message Queuing Protocol,高级消息队列协议)是一个开放标准的应用层协议,旨在为消息中间件提供一种统一的、标准的通信方式。它允许消息在分布式系统中的应用程序之间进行可靠的、异步的传递。AMQ…

console调试

简介 浏览器的开发者工具为我们提供了强大的调试系统,可以用来查看DOM树结构、CSS样式调试、动画调试、JavaScript代码断点调试等。今天我们就来看看console调试的那些实用的调试技巧。 我们使用最多的就是console.log()了,当然多数情况下,…

0813,引用,函数重载,内存布局叭叭叭

是我4句话5个ERROR&#xff0c;阿巴阿巴 001_arrpointer.cc #include <iostream> using std::cout; using std::endl;void test(){int a[5]{1,2,3,4,5};int (*p)[5]&a;cout<<p<<endl;cout<<p1<<endl;int *pp(int*)(&a1);//第二个数组的…

vscode + cmake + ninja + ARMCC 配置stm32开发环境(构建篇)

vscode cmake ninja ARMCC 配置stm32开发环境&#xff08;构建篇&#xff09; 1. 前置环境 1.1 cmake安装 从CMake官网上下载CMake安装包进行安装CMake。CMake官网 安装完成之后&#xff0c;使用cmd查看cmake是否添加进入环境变量。 1.2 LLVM套件安装 从LLVM的github…