zoukankan      html  css  js  c++  java
  • 爬取链家北京市二手房的单个房源页的详细i信息

    1、环境安装

    (1)安装Anaconda:

      下载地址:https://www.anaconda.com/products/individual

    (2)安装:scrapy

    (3)安装:Pycharm

    (4)安装:Xpath helper

      教程参考:

        获取插件:https://blog.csdn.net/weixin_41010318/article/details/86472643

        配置过程:https://www.cnblogs.com/pfeiliu/p/13483562.html

    2、爬取过程

    (1)网页分析:

      网址:

        每个房源页网址都是:https://bj.lianjia.com/ershoufang/  下的房源标题链接;

        上次爬取了每个房源页链接的链接信息,并保存到了json文件中,可以逐个调用文件中的链接信息进行所有页面的爬取;

        

      利用xpath helper 分析出需要爬取的字段:

      

      

      

      

    (2)详细代码:

      目录:

      

    创建项目:

    # 打开Pycharm,并打开Terminal,执行以下命令

    scrapy startproject LJbasicInformation
    cd LJbasicInformation
    scrapy genspider lianjiaBj bj.lianjia.com

    在scrapy.cfg同级目录,创建run.py,用于启动Scrapy项目,内容如下

    # 在项目根目录下新建:run.py
    from scrapy.cmdline import execute
    # 第三个参数是:爬虫程序名
    # --nolog什么意思?
    execute(['scrapy', 'crawl', 'lianjiaBj'])
    View Code

    lianjiaBj.py

    import scrapy
    # -*- coding: utf-8 -*-
    from LJbasicInformation.items import LjbasicinformationItem
    from selenium.webdriver import ChromeOptions
    from selenium.webdriver import Chrome
    import json
    
    # 引入文件1max_beijing.json,利用文件内的url网址信息
    # 读取各城市的json文件
    with open('./url_json/max1_beijing.json', 'r') as file:
        str = file.read()
        data = json.loads(str)
    
    
    class LianjiabjSpider(scrapy.Spider):
        name = 'lianjiaBj'
        # allowed_domains = ['bj.lianjia.com']
        start_urls = data
    
        # 实例化一个浏览器对象
        def __init__(self):
            # 防止网站识别Selenium代码
            # selenium启动配置参数接收是ChromeOptions类,创建方式如下:
            options = ChromeOptions()
            # 添加启动参数
            # 浏览器不提供可视化页面. linux下如果系统不支持可视化不加这条会启动失败
            options.add_argument("--headless")  # => 为Chrome配置无头模式
            # 添加实验性质的设置参数
            # 设置开发者模式启动,该模式下webdriver属性为正常值
            options.add_experimental_option('excludeSwitches', ['enable-automation'])
            options.add_experimental_option('useAutomationExtension', False)
            # 禁用浏览器弹窗
            self.browser = Chrome(options=options)
            # 最新解决navigator.webdriver=true的方法
            self.browser.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
                "source": """
                                       Object.defineProperty(navigator, 'webdriver', {
                                         get: () => undefined
                                       })
                                     """
            })
    
            super().__init__()
    
        def start_requests(self):
            print("开始爬虫")
            url = self.start_urls
            print("开始接触url")
            print(type(url))
            count = 0
            # 逐个引入1max_beijing.json文件中url信息
            for i in url:
                count += 1
                alone_url = i['BeiJingFangYuan_Id']  # dataNum为 str类型的地址
                # print(alone_url)
    
                # print("url", url)
                # 访问下一页,有返回时,调用self.parse_details方法
                response = scrapy.Request(url=alone_url, callback=self.parse_details)
                yield response
            print("本次爬取数据: %s条" % count)
    
            # 一个Request对象表示一个HTTP请求,它通常是在爬虫生成,并由下载执行,从而生成Response
            # url(string) - 此请求的网址
            # callback(callable) - 将使用此请求的响应(一旦下载)作为其第一个参数调用的函数。
            # 如果请求没有指定回调,parse()将使用spider的 方法。请注意,如果在处理期间引发异常,则会调用errback。
            # 仍有许多参数:method='GET', headers, body, cookies, meta, encoding='utf-8', priority=0, dont_filter=False, errback
            # response = scrapy.Request(url=url, callback=self.parse_index)      #
            # yield response
    
            # 整个爬虫结束后关闭浏览器
            def close(self, spider):
                print("关闭爬虫")
                self.browser.quit()
    
        ''' # 访问主页的url, 拿到对应板块的response
        def parse_index(self, response):
            print("访问主页")
    
            for i in range(0, 2970):
                # 下一页url
                url = url[i]['BeiJingFangYuan_Id']
                i += 1
                print("url", url)
                # 访问下一页,有返回时,调用self.parse_details方法
                yield scrapy.Request(url=url, callback=self.parse_details)'''
    
        def parse_details(self, response):
            try:
                # #基本属性
                # 房屋户型//div[@class="base"]//li[1]/text()
                fangWuHuXing = response.xpath('//div[@class="base"]//li[1]/text()').extract()
    
                # 建筑面积//div[@class="base"]//li[3]/text()
                jianZhuMianJi = response.xpath('//div[@class="base"]//li[3]/text()').extract()
    
                # 套内面积//div[@class="base"]//li[5]/text()
                taoNeiMianJi = response.xpath('//div[@class="base"]//li[5]/text()').extract()
    
                # 房屋朝向//div[@class="base"]//li[7]/text()
                fangWuChaoXiang = response.xpath('//div[@class="base"]//li[7]/text()').extract()
    
                # 装修情况//div[@class="base"]//li[9]/text()
                zhuangXiuQingKuang = response.xpath('//div[@class="base"]//li[9]/text()').extract()
    
                # 供暖方式//div[@class="base"]//li[11]/text()
                gongNuanFangShi = response.xpath('//div[@class="base"]//li[11]/text()').extract()
    
                # 所在楼层//div[@class="base"]//li[2]/text()
                suoZaiLouCeng = response.xpath('//div[@class="base"]//li[2]/text()').extract()
    
                # 户型结构//div[@class="base"]//li[4]/text()
                huXingJieGou = response.xpath('//div[@class="base"]//li[4]/text()').extract()
    
                # 建筑类型//div[@class="base"]//li[6]/text()
                jianZhuLeiXing = response.xpath('//div[@class="base"]//li[6]/text()').extract()
    
                # 建筑结构//div[@class="base"]//li[8]/text()
                jianZhuJieGou = response.xpath('//div[@class="base"]//li[8]/text()').extract()
    
                # 梯户比例//div[@class="base"]//li[10]/text()
                tiHuBiLi = response.xpath('//div[@class="base"]//li[10]/text()').extract()
    
                # 配备电梯//div[@class="base"]//li[12]/text()
                peiBeiDianTi = response.xpath('//div[@class="base"]//li[12]/text()').extract()
    
    
                # #交易属性
                # 挂牌时间//div[@class="transaction"]//li[1]/span[2]/text()
                guaPaiShiJian = response.xpath('//div[@class="transaction"]//li[1]/span[2]/text()').extract()
    
                # 上次交易//div[@class="transaction"]//li[3]/span[2]/text()
                shangCiJiaoYi = response.xpath('//div[@class="transaction"]//li[3]/span[2]/text()').extract()
    
                # 房屋年限//div[@class="transaction"]//li[5]/span[2]/text()
                fangWuNianXian = response.xpath('//div[@class="transaction"]//li[5]/span[2]/text()').extract()
    
                # 抵押信息//div[@class="transaction"]//li[7]/span[2]/@title
                diYaXinXi = response.xpath('//div[@class="transaction"]//li[7]/span[2]/text()').extract()
    
                # 交易权属//div[@class="transaction"]//li[2]/span[2]/text()
                jiaoYiQuanShu = response.xpath('//div[@class="transaction"]//li[2]/span[2]/text()').extract()
    
                # 房屋用途//div[@class="transaction"]//li[4]/span[2]/text()
                fangWuYongTu = response.xpath('//div[@class="transaction"]//li[4]/span[2]/text()').extract()
    
                # 产权所属//div[@class="transaction"]//li[6]/span[2]/text()
                chanQuanSuoShu = response.xpath('//div[@class="transaction"]//li[6]/span[2]/text()').extract()
    
                # 房本备件//div[@class="transaction"]//li[8]/span[2]/text()
                fangBenBeiJian = response.xpath('//div[@class="transaction"]//li[8]/span[2]/text()').extract()
    
                # #房源特色
                # 核心卖点//div[@class="introContent showbasemore"]//div[2]/div[@class="content"]/text()
                heXinMaiDian = response.xpath('//div[@class="introContent showbasemore"]//div[2]/div[@class="content"]/text()').extract()
    
                # 小区介绍//div[@class="introContent showbasemore"]//div[3]/div[@class="content"]/text()
                xiaoQuJieShao = response.xpath('//div[@class="introContent showbasemore"]//div[3]/div[@class="content"]/text()').extract()
    
                # 户型介绍//div[@class="introContent showbasemore"]//div[4]/div[@class="content"]/text()
                huXingJieShao = response.xpath('//div[@class="introContent showbasemore"]//div[4]/div[@class="content"]/text()').extract()
    
                # 周边配套//div[@class="introContent showbasemore"]//div[5]/div[@class="content"]/text()
                zhouBianPeiTao = response.xpath('//div[@class="introContent showbasemore"]//div[5]/div[@class="content"]/text()').extract()
    
    
                # #房源标题//h1[@class="main"]/text()
                fangYuanBiaoTi = response.xpath('//h1[@class="main"]/text()').extract()
    
    
                # #价格信息
                # 房源总价//div[@class="content"]/div[3]/span[1]/text()
                fangYuanZongJie = response.xpath('//div[@class="content"]/div[3]/span[1]/text()').extract()
    
                # 平方价格//span[@class="unitPriceValue"]/text()
                pingFangJiaGe = response.xpath('//span[@class="unitPriceValue"]/text()').extract()
    
                # 建成时间//div[@class="subInfo noHidden"]/text()[1]
                jianChengShiJian = response.xpath('//div[@class="subInfo noHidden"]/text()[1]').extract()
    
    
                # #房子信息
                # 小区名称//div[@class="communityName"]/a[1]/text()
                xiaoQuMingCheng = response.xpath('//div[@class="communityName"]/a[1]/text()').extract()
    
                # 所在区域
                # //div[@class="areaName"]/span[2]/a[1]/text()
                suoZaiQuYu1 = response.xpath('//div[@class="areaName"]/span[2]/a[1]/text()').extract()
                # //div[@class="areaName"]/span[2]/a[2]/text()
                suoZaiQuYu2 = response.xpath('//div[@class="areaName"]/span[2]/a[2]/text()').extract()
                # //div[@class="areaName"]/span[2]/text()
                suoZaiQuYu3 = response.xpath('//div[@class="areaName"]/span[2]/text()').extract()
    
                # 看房时间//div[@class="visitTime"]/span[2]/text()
                kanFangShiJian = response.xpath('//div[@class="visitTime"]/span[2]/text()').extract()
    
                # 链家编号//div[@class="houseRecord"]/span[2]/text()
                lianJiaBianHao = response.xpath('//div[@class="houseRecord"]/span[2]/text()').extract()
    
    
    
                # item
                item = LjbasicinformationItem()
                # 基本属性
                item['fangWuHuXing'] = fangWuHuXing
                item['jianZhuMianJi'] = jianZhuMianJi
                item['taoNeiMianJi'] = taoNeiMianJi
                item['fangWuChaoXiang'] = fangWuChaoXiang
                item['zhuangXiuQingKuang'] = zhuangXiuQingKuang
                item['gongNuanFangShi'] = gongNuanFangShi
                item['suoZaiLouCeng'] = suoZaiLouCeng
                item['huXingJieGou'] = huXingJieGou
                item['jianZhuLeiXing'] = jianZhuLeiXing
                item['jianZhuJieGou'] = jianZhuJieGou
                item['tiHuBiLi'] = tiHuBiLi
                item['peiBeiDianTi'] = peiBeiDianTi
    
                # 交易属性
                item['guaPaiShiJian'] = guaPaiShiJian
                item['shangCiJiaoYi'] = shangCiJiaoYi
                item['fangWuNianXian'] = fangWuNianXian
                item['diYaXinXi'] = diYaXinXi
                item['jiaoYiQuanShu'] = jiaoYiQuanShu
                item['fangWuYongTu'] = fangWuYongTu
                item['chanQuanSuoShu'] = chanQuanSuoShu
                item['fangBenBeiJian'] = fangBenBeiJian
    
                # 房源特色
                item['heXinMaiDian'] = heXinMaiDian
                item['xiaoQuJieShao'] = xiaoQuJieShao
                item['huXingJieShao'] = huXingJieShao
                item['zhouBianPeiTao'] = zhouBianPeiTao
    
                # 房源标题
                item['fangYuanBiaoTi'] = fangYuanBiaoTi
    
                # 价格信息
                item['fangYuanZongJie'] = fangYuanZongJie
                item['pingFangJiaGe'] = pingFangJiaGe
                item['jianChengShiJian'] = jianChengShiJian
    
                # 房子信息
                item['xiaoQuMingCheng'] = xiaoQuMingCheng
                item['suoZaiQuYu1'] = suoZaiQuYu1
                item['suoZaiQuYu2'] = suoZaiQuYu2
                item['suoZaiQuYu3'] = suoZaiQuYu3
                item['kanFangShiJian'] = kanFangShiJian
                item['lianJiaBianHao'] = lianJiaBianHao
    
                yield item
            except Exception as e:
                print(e)
    View Code

    items.py

    import scrapy
    
    class LjbasicinformationItem(scrapy.Item):
        # define the fields for your item here like:
        # name = scrapy.Field()
        # #基本属性
        # 房屋户型
        fangWuHuXing = scrapy.Field()
        # 建筑面积
        jianZhuMianJi = scrapy.Field()
        # 套内面积
        taoNeiMianJi = scrapy.Field()
        # 房屋朝向
        fangWuChaoXiang = scrapy.Field()
        # 装修情况
        zhuangXiuQingKuang = scrapy.Field()
        # 供暖方式
        gongNuanFangShi = scrapy.Field()
        # 所在楼层
        suoZaiLouCeng = scrapy.Field()
        # 户型结构
        huXingJieGou = scrapy.Field()
        # 建筑类型
        jianZhuLeiXing = scrapy.Field()
        # 建筑结构
        jianZhuJieGou = scrapy.Field()
        # 梯户比例
        tiHuBiLi = scrapy.Field()
        # 配备电梯
        peiBeiDianTi = scrapy.Field()
    
        # #交易属性
        # 挂牌时间
        guaPaiShiJian = scrapy.Field()
        # 上次交易
        shangCiJiaoYi = scrapy.Field()
        # 房屋年限
        fangWuNianXian = scrapy.Field()
        # 抵押信息
        diYaXinXi = scrapy.Field()
        # 交易权属
        jiaoYiQuanShu = scrapy.Field()
        # 房屋用途
        fangWuYongTu = scrapy.Field()
        # 产权所属
        chanQuanSuoShu = scrapy.Field()
        # 房本备件
        fangBenBeiJian = scrapy.Field()
    
        # #房源特色
        # 核心卖点
        heXinMaiDian = scrapy.Field()
        # 小区介绍
        xiaoQuJieShao = scrapy.Field()
        # 户型介绍
        huXingJieShao = scrapy.Field()
        # 周边配套
        zhouBianPeiTao = scrapy.Field()
    
        # #房源标题
        fangYuanBiaoTi = scrapy.Field()
    
        # #价格信息
        # 房源总价
        fangYuanZongJie = scrapy.Field()
        # 平方价格
        pingFangJiaGe = scrapy.Field()
        # 建成时间
        jianChengShiJian = scrapy.Field()
    
        # #房子信息
        # 小区名称
        xiaoQuMingCheng = scrapy.Field()
        # 所在区域
        suoZaiQuYu1 = scrapy.Field()
        suoZaiQuYu2 = scrapy.Field()
        suoZaiQuYu3 = scrapy.Field()
        # 看房时间
        kanFangShiJian = scrapy.Field()
        # 链家编号
        lianJiaBianHao = scrapy.Field()
    View Code

    pipelines.py

    import codecs, json
    
    class LjbasicinformationPipeline(object):
        def __init__(self):
            # python3保存文件 必须需要'w' 保存为json格式
            # self.f = open("max_BJ_information.json", 'wb')
            self.file = codecs.open('fangyuan_BJ_information.json', 'w', encoding="utf-8")
    
    
        def process_item(self, item, spider):
            # 读取item中的数据 并换行处理
            content = json.dumps(dict(item), ensure_ascii=False) + ',
    '
            self.file.write(content)
    
            return item
    
        def close_spider(self, spider):
            # 关闭文件
            self.file.close()
    View Code

    修改settings.py,应用pipelines

    # Scrapy settings for LJbasicInformation project
    #
    # For simplicity, this file contains only settings considered important or
    # commonly used. You can find more settings consulting the documentation:
    #
    #     https://docs.scrapy.org/en/latest/topics/settings.html
    #     https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
    #     https://docs.scrapy.org/en/latest/topics/spider-middleware.html
    
    BOT_NAME = 'LJbasicInformation'
    
    SPIDER_MODULES = ['LJbasicInformation.spiders']
    NEWSPIDER_MODULE = 'LJbasicInformation.spiders'
    
    
    # Crawl responsibly by identifying yourself (and your website) on the user-agent
    #USER_AGENT = 'LJbasicInformation (+http://www.yourdomain.com)'
    
    # Obey robots.txt rules
    ROBOTSTXT_OBEY = False
    
    # Configure maximum concurrent requests performed by Scrapy (default: 16)
    #CONCURRENT_REQUESTS = 32
    
    # Configure a delay for requests for the same website (default: 0)
    # See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
    # See also autothrottle settings and docs
    #DOWNLOAD_DELAY = 3
    # The download delay setting will honor only one of:
    #CONCURRENT_REQUESTS_PER_DOMAIN = 16
    #CONCURRENT_REQUESTS_PER_IP = 16
    
    # Disable cookies (enabled by default)
    #COOKIES_ENABLED = False
    
    # Disable Telnet Console (enabled by default)
    #TELNETCONSOLE_ENABLED = False
    
    # 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',
    #}
    
    # Enable or disable spider middlewares
    # See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
    #SPIDER_MIDDLEWARES = {
    #    'LJbasicInformation.middlewares.LjbasicinformationSpiderMiddleware': 543,
    #}
    
    # Enable or disable downloader middlewares
    # See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
    #DOWNLOADER_MIDDLEWARES = {
    #    'LJbasicInformation.middlewares.LjbasicinformationDownloaderMiddleware': 543,
    #}
    
    # Enable or disable extensions
    # See https://docs.scrapy.org/en/latest/topics/extensions.html
    #EXTENSIONS = {
    #    'scrapy.extensions.telnet.TelnetConsole': None,
    #}
    
    # Configure item pipelines
    # See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
    ITEM_PIPELINES = {
        'LJbasicInformation.pipelines.LjbasicinformationPipeline': 300,
    }
    
    # Enable and configure the AutoThrottle extension (disabled by default)
    # See https://docs.scrapy.org/en/latest/topics/autothrottle.html
    #AUTOTHROTTLE_ENABLED = True
    # The initial download delay
    #AUTOTHROTTLE_START_DELAY = 5
    # The maximum download delay to be set in case of high latencies
    #AUTOTHROTTLE_MAX_DELAY = 60
    # The average number of requests Scrapy should be sending in parallel to
    # each remote server
    #AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
    # Enable showing throttling stats for every response received:
    #AUTOTHROTTLE_DEBUG = False
    
    # Enable and configure HTTP caching (disabled by default)
    # See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
    #HTTPCACHE_ENABLED = True
    #HTTPCACHE_EXPIRATION_SECS = 0
    #HTTPCACHE_DIR = 'httpcache'
    #HTTPCACHE_IGNORE_HTTP_CODES = []
    #HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
    View Code

    执行run.py,启动爬虫项目,效果如下:

  • 相关阅读:
    201671010146 2017-2 <表格监督>
    201671010146 2017-2 《Java学期末有感》
    201671010146 2017-2 《Java线程》
    201671010146 2017-2 《第十六周学习Java有感》
    201671010146 2017―2 《第16周学习java有感》
    201671010146 2017―2 《第十五周学习java有感》
    201671010146 2017-2 《java第十一章学习感悟》
    201671010146 2017-2 《第十章学习感悟》
    201671010146 2017―2 《第11周学习java有感》
    201671010146 2017-2 《java第八章学习感悟》
  • 原文地址:https://www.cnblogs.com/mrfanqie/p/lianjiaproject_03.html
Copyright © 2011-2022 走看看