首页 > 其他分享 >Scrapy爬取链家数据(二):爬取小区详细信息

Scrapy爬取链家数据(二):爬取小区详细信息

时间:2024-09-23 21:50:09浏览次数:7  
标签:span text 链家 爬取 Scrapy div extract class first

前言

       上一篇文章中有朋友问不能正确获取页面,一个原因是没有设置不遵守爬虫协议,设置方法如下,在settings.py文件中,将图中字段设置为False即可:

# Obey robots.txt rules
ROBOTSTXT_OBEY = False

        在上一篇文章中,我们通过相关命令,引入了Scrapy框架,并且成功运行了第一个爬虫,获取了北京朝阳地区某个小区的名称。在这篇文章中,我们将继续获取小区其他信息,比如小区位置、建筑年代、楼栋数、户数等。

1. 构建小区信息数据结构

        在上一篇文章中项目结构简介章节中,我们介绍了items.py文件的用处,简单来说,该文件是用来定义爬虫最终返回数据的具体内容。我们在该文件中通过XiaoquItem类定义小区所有相关信息如下:


# '小区ID': xiao_id,
# '小区名称': xiao_name,
# '位置': position
# '挂牌平均价': average_price,
# '产权类型': right_type
# '供暖方式' heat
# '房屋总数': total_house,
# '楼栋总数': total_building
# '建成年代': complete_year,
# '开发商': developer,
# '用水类型': water,
# '用电类型': electricity,
# '绿化率': green_ratio,
# '容积率': plot_ratio,
# '价格变动记录': price_info
# '连接': url
class XiaoquItem(scrapy.Item):
    xiao_id = scrapy.Field()
    xiao_name = scrapy.Field()
    position = scrapy.Field()
    average_price = scrapy.Field()
    right_type = scrapy.Field()
    heat = scrapy.Field()
    total_house = scrapy.Field()
    complete_year = scrapy.Field()
    developer = scrapy.Field()
    total_building = scrapy.Field()
    water = scrapy.Field()
    electricity = scrapy.Field()
    green_ratio = scrapy.Field()
    plot_ratio = scrapy.Field()
    price_info = scrapy.Field()
    url = scrapy.Field()
    pass

在该文件中,通过class来定义小区信息结构体,该类继承了scrapy.Item类。按照官方文档解释,Field类相当于Python内置字典类的一个别名,并没有提供额外的方法和属性。在此阶段,我们可以默认为这是Scrapy中通用写法即可,如果想深入了解Field()实现,可以进入对应源码查看。

2. 解析页面中数据

        定义完小区数据结构后,就需要在链家页面中找到数据结构中对应字段的值。Scrapy中使用 Xpath作为HTML页面解析器,可以帮助爬虫定位和提取 HTML 或 XML 文档中的数据。在具体解析页面之前,可以安装一个浏览器Xpath插件,该类型插件具体作用是帮助我们快速定位元素,即告诉我们页面中某个dom元素的Xpath表示方法。某款插件效果如下:

在该图片中,顶部QUERY为Xpath语法,RESULTS为页面元素。如果我们想在页面中定位芍药居北里8月二手房参考均价的dom位置,就应该使用如下Xpath语法进行定位。

/div[@class='leftContent']/ul[@class='listContent']/li[@class='clear xiaoquListItem'][1]/div[@class='xiaoquListItemRight']/div[@class='xiaoquListItemPrice']/div[@class='totalPrice']/span

链家小区详情页面如下:

由于链家页面布局一致性,在某Xpath插件辅助下,得到了XiaoquItem结构体中数据的值在页面中对应定位方法如下:


('//div[@class="xiaoquDetailHeaderContent clear"]/div[@class="detailHeader fl"]/h1/text()').extract_first()
('//div[@class="xiaoquDetailHeaderContent clear"]/div[@class="detailHeader fl"]/div[@class="detailDesc"]/text()').extract_first()
('//div[@class="xiaoquPrice clear"]/div[@class="fl"]/span[@class="xiaoquUnitPrice"]/text()').extract_first()
('//div[@class="xiaoquInfoItemMulty"]/div[@class="xiaoquInfoItemCol"][1]/div[@class="xiaoquInfoItem"][2]/span[@class="xiaoquInfoContent"]/text()').extract_first()
('//div[@class="xiaoquInfoItemMulty"]/div[@class="xiaoquInfoItemCol"][2]/div[@class="xiaoquInfoItem"][2]/span[@class="xiaoquInfoContent"]/text()').extract_first()
('//div[@class="xiaoquInfoItemMulty"]/div[@class="xiaoquInfoItemCol"][2]/div[@class="xiaoquInfoItem"][1]/span[@class="xiaoquInfoContent"]/text()').extract_first()
('//div[@class="xiaoquInfoItemMulty"]/div[@class="xiaoquInfoItemCol"][2]/div[@class="xiaoquInfoItem"][3]/span[@class="xiaoquInfoContent"]/text()').extract_first()
('//div[@class="xiaoquInfoItemOneLine"]/div[@class="xiaoquInfoItem outerItem"][4]/span[@class="xiaoquInfoContent outer"]/text()').extract_first()
('//div[@class="xiaoquInfoItemMulty"]/div[@class="xiaoquInfoItemCol"][1]/div[@class="xiaoquInfoItem"][3]/span[@class="xiaoquInfoContent"]/text()').extract_first()
('//div[@class="xiaoquInfoItemMulty"]/div[@class="xiaoquInfoItemCol"][2]/div[@class="xiaoquInfoItem"][4]/span[@class="xiaoquInfoContent"]/text()').extract_first()
('//div[@class="xiaoquInfoItemMulty"]/div[@class="xiaoquInfoItemCol"][2]/div[@class="xiaoquInfoItem"][5]/span[@class="xiaoquInfoContent"]/text()').extract_first()
('//div[@class="xiaoquInfoItemMulty"]/div[@class="xiaoquInfoItemCol"][1]/div[@class="xiaoquInfoItem"][4]/span[@class="xiaoquInfoContent"]/text()').extract_first()
('//div[@class="xiaoquInfoItemMulty"]/div[@class="xiaoquInfoItemCol"][1]/div[@class="xiaoquInfoItem"][5]/span[@class="xiaoquInfoContent"]/text()').extract_first()

在页面找到了对应元素的值,然后我们将这些值赋给XiaoquItem结构体。我们将lianjiaxiaoqu.py文件改造如下:

import scrapy

from lianjia.items import XiaoquItem


class LianjiaxiaoquSpider(scrapy.Spider):
    name = "lianjiaxiaoqu"
    allowed_domains = ["lianjia.com"]
    start_urls = ["https://bj.lianjia.com/xiaoqu/chaoyang/y4/"]

    def parse(self, response):

        url = response.xpath('//div[@class="info"]/div[@class="title"]/a/@href').extract()[0]
        yield scrapy.Request(url, callback=self.parse_info)


    def parse_info(self, response):
        item = XiaoquItem()
        item['xiao_id'] = response.url.split('/')[-2]
        item["xiao_name"] = response.xpath(
            '//div[@class="xiaoquDetailHeaderContent clear"]/div[@class="detailHeader fl"]/h1/text()').extract_first()
        item["position"] = response.xpath(
            '//div[@class="xiaoquDetailHeaderContent clear"]/div[@class="detailHeader fl"]/div[@class="detailDesc"]/text()').extract_first()
        item["average_price"] = response.xpath(
            '//div[@class="xiaoquPrice clear"]/div[@class="fl"]/span[@class="xiaoquUnitPrice"]/text()').extract_first()
        item["total_house"] = response.xpath(
            '//div[@class="xiaoquInfoItemMulty"]/div[@class="xiaoquInfoItemCol"][1]/div[@class="xiaoquInfoItem"][2]/span[@class="xiaoquInfoContent"]/text()').extract_first()
        item["complete_year"] = response.xpath(
            '//div[@class="xiaoquInfoItemMulty"]/div[@class="xiaoquInfoItemCol"][2]/div[@class="xiaoquInfoItem"][2]/span[@class="xiaoquInfoContent"]/text()').extract_first()
        item["right_type"] = response.xpath(
            '//div[@class="xiaoquInfoItemMulty"]/div[@class="xiaoquInfoItemCol"][2]/div[@class="xiaoquInfoItem"][1]/span[@class="xiaoquInfoContent"]/text()').extract_first()
        item["heat"] = response.xpath(
            '//div[@class="xiaoquInfoItemMulty"]/div[@class="xiaoquInfoItemCol"][2]/div[@class="xiaoquInfoItem"][3]/span[@class="xiaoquInfoContent"]/text()').extract_first()
        item["developer"] = response.xpath(
            '//div[@class="xiaoquInfoItemOneLine"]/div[@class="xiaoquInfoItem outerItem"][4]/span[@class="xiaoquInfoContent outer"]/text()').extract_first()
        item["total_building"] = response.xpath(
            '//div[@class="xiaoquInfoItemMulty"]/div[@class="xiaoquInfoItemCol"][1]/div[@class="xiaoquInfoItem"][3]/span[@class="xiaoquInfoContent"]/text()').extract_first()
        item["water"] = response.xpath(
            '//div[@class="xiaoquInfoItemMulty"]/div[@class="xiaoquInfoItemCol"][2]/div[@class="xiaoquInfoItem"][4]/span[@class="xiaoquInfoContent"]/text()').extract_first()
        item["electricity"] = response.xpath(
            '//div[@class="xiaoquInfoItemMulty"]/div[@class="xiaoquInfoItemCol"][2]/div[@class="xiaoquInfoItem"][5]/span[@class="xiaoquInfoContent"]/text()').extract_first()
        item["green_ratio"] = response.xpath(
            '//div[@class="xiaoquInfoItemMulty"]/div[@class="xiaoquInfoItemCol"][1]/div[@class="xiaoquInfoItem"][4]/span[@class="xiaoquInfoContent"]/text()').extract_first()
        item["plot_ratio"] = response.xpath(
            '//div[@class="xiaoquInfoItemMulty"]/div[@class="xiaoquInfoItemCol"][1]/div[@class="xiaoquInfoItem"][5]/span[@class="xiaoquInfoContent"]/text()').extract_first()
        print(item)

相比于(一)中lianjiaxiaoqu.py文件,主要变化:(1)将页面信息解析过程封装成parse_info()方法,供pars()方法调用。(2)在parse()方法中,首先获取小区展示页面中隐藏的小区详情页面url,其次对小区详情页面中内容发起请求,获得相应页面后,通过parse_info()方法进行解析,获得相应信息并赋值给item。(3)最后打印item,获得某个小区信息。

之所以在parse方法中再次进行url请求,是因为链家页面组织在组织结构上进行类分级。通过爬虫入口得到的页面,是小区展示列表页,该页面只包含小区部分信息。通过点击列表页中某个小区标题,才能跳转至小区详情页面,该页面包含小区具体信息。

        改造完lianjiaxiaoqu.py爬虫文件后,通过以下命令运行该爬虫:

scrapy crawl lianjiaxiaoqu

成功运行后,得到如下结果:

 

可以发现我们成功获取某个小区详细信息,同时小区信息上发两次请求过程也证实了parse()方法中请求顺序的正确性。 

3. 总结

        通过上述内容,我们成功获取了某个小区全部详情信息。下一片文章将介绍如何获取小区展示页面中全部小区详细信息以及信息入库。就上述内容如有问题,欢迎留言。 

 

标签:span,text,链家,爬取,Scrapy,div,extract,class,first
From: https://blog.csdn.net/somanybeans/article/details/142443057

相关文章

  • 【采集软件】爬取小红书关键词笔记下的评论
    一、背景分析1.1开发背景众所周知,小红薯是国内流量数一数二的社区种草平台,拥有海量用户和上亿日活,尤其笔记下方的评论区有重大挖掘价值。采集小红书评论数据可以帮助客户了解消费者对商品和品牌的评价和反馈,从而更好地洞悉消费者的喜好、需求和购买意向。基于此,我用python开发了一......
  • 七、Scrapy框架-案例1
    1.豆瓣民谣Top排名爬取1.1构建scrapy项目安装Scrapy库pipinstallscrapy创建Scrapy项目通过cmd进入命令窗口,执行命令scrapystartprojectxxxx(xxxx为scrapy项目名),创建scrapy项目。scrapystartprojectdouban_spider2024创建爬虫项目执行scrapygenspider......
  • 【python爬虫案例】利用python爬取豆瓣读书评分TOP250排行数据
    一、爬取案例-豆瓣读书TOP250上一期给大家分享了个python爬虫案例:豆瓣电影TOP250的排行榜数据爬取【python爬虫案例】利用python爬虫爬取豆瓣电影评分TOP250排行数据!今天再给大家分享一下:豆瓣读书排行榜TOP250的python爬虫案例!因为是同一个网站,所以流程和逻辑上都是差不多的。......
  • C# html数据爬取与过滤
    1.首先安装第三方HTML数据过滤包HtmlAgilityPack我爬取的网站是一个树洞网站:https://i.jandan.net/treehole,他是一个单体网站,不通过api请求,所以只能根据HTML过滤,他的分页是通过base64加密的 这是获取到的部分数据,这是我们需要的有效数据,他是有固定结构的,我们只要筛选这里......
  • 【问题解决】Web在线办公系统-数据爬取结果乱码
    问题描述在【热门电影】模块,通过jsoup爬虫并解析网页数据时,执行代码,出现“中文乱码”问题。解决方法由于网页自带的编码方式与后端开发中jsoup解析的编码方式不匹配,需要修改后端解析网页的编码方式。//设置爬取网页的地址Stringurl="https://movie.douban.com/......
  • 如何用Python爬取全部ETF基金实时数据!
    一般来说,我们都是交易ETF基金,就是可以在股票交易所买卖的那种基金,而不是基金公司或者天天基金网提供的基金。因为ETF基金的交易方式类似股票,当时会比股票更有优势,这个具体我们就不展开讲,不然跑题了。言归正传,我们来爬取全部800多只ETF基金的数据。1).打开东财的网站,点击基金,......
  • 【python爬虫案例】利用python爬取豆瓣电影TOP250评分排行数据!
    一、爬取对象-豆瓣电影TOP250今天给大家分享一期豆瓣读书TOP排行榜250的python爬虫案例爬取的目标网址是:https://movie.douban.com/top250咱们以目标为驱动,以兴趣为导向,先来看下爬虫程序运行后得到的excel文档数据那代码是如何实现豆瓣电影TOP250数据爬取的了?下面逐一讲解一......
  • springboot基于java的高校电子图书馆的大数据平台规划与设计(源码+vue+scrapy+hive+可
    收藏关注不迷路!!......
  • 入门级小白超实用的python爬虫爬取网页图片
    图像作为信息传播的重要载体,在日常生活和各行各业的应用越来越广泛。网络图片爬取成为了数据挖掘和分析领域的一项重要技术。本文将探讨在网络环境中爬取图片的实现步骤以及代码。效果展示代码运行后,输入关健字等待片刻后桌面会自动创建一个名为picture的文件夹随后开始爬......
  • 【python爬虫案例】利用python爬取豆瓣电影TOP250评分排行数据!
    目录一、爬取对象-豆瓣电影TOP250二、豆瓣电影网站分析三、python爬虫代码详解三、完整源码获取一、爬取对象-豆瓣电影TOP250今天给大家分享一期豆瓣读书TOP排行榜250的python爬虫案例爬取的目标网址是:豆瓣电影Top250咱们以目标为驱动,以兴趣为导向,先来看下爬虫程......