开发Python网络爬虫应用,爬取链家新房楼盘信息保存到mongodb中,并分析相关数据

这里写自定义目录标题

  • 爬取代码
  • 分析数据
  • 问题

爬取代码

import requests
import time
from lxml import html
from pymongo import MongoClient
import random

BASEURL = 'https://cq.fang.lianjia.com/loupan/'

# 获取某市区域的所有链接
def get_areas(url):
    print('获取区县列表')
    # 设置请求头
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'}
    # 获取请求页面数据
    res = requests.get(url, headers=headers)
    content = html.fromstring(res.text)
    # 获取区县名称文本
    areas = content.xpath('//div[@class="filter-by-area-container"]/ul[@class="district-wrapper"]/li/text()')
    # 区县太多,只设置主城九区
    areas = ['江北', '渝北', '渝中', '沙坪坝', '九龙坡', '南岸', '大渡口', '巴南', '北碚']
    # areas = ['大足', '武隆区', '石柱', '涪陵', '綦江','长寿', '江津', '合川', '南川', '璧山', '铜梁', '潼南', '万州', '梁平', '云阳', '黔江', '双桥 ', '永川', '丰都', '秀山土家族苗族自治县', '忠县', '巫山县', '荣昌区', '奉节县', '开州区', '垫江县', '酉阳土家族苗族自治县', '彭水苗族土家族自治县', '巫溪县', '城口县']
    print(areas)
    # 获取区县名称拼写
    areas_link = content.xpath('//div[@class="filter-by-area-container"]/ul[@class="district-wrapper"]/li/@data-district-spell')
    # 区县太多,只设置主城九区
    areas_link = ['jiangbei', 'yubei', 'yuzhong', 'shapingba', 'jiulongpo', 'nanan', 'dadukou', 'banan', 'beibei']
    # areas_link = ['dazu', 'wulongqu', 'shizhu', 'fuling', 'qijiang', 'changshou1', 'jiangjing', 'hechuang', 'nanchuang', 'bishan', 'tongliang', 'tongnan', 'wanzhou', 'liangping', 'yunyang', 'qianjiang', 'shuangqiao1', 'yongchuan', 'fengdu1', 'xiushantujiazumiaozuzizhixian', 'zhongxian', 'wushanxian1', 'rongchangqu', 'fengjiexian', 'kaizhouqu', 'dianjiangxian', 'youyangtujiazumiaozuzizhixian', 'pengshuimiaozutujiazuzizhixian', 'wuxixian', 'chengkouxian']
    # print(areas_link)
    if not areas:
        print("主站页面未获取成功,请手动查看页面是否需要人机验证!")
        return
    # 遍历获取所有区县的链接
    for i in range(0, len(areas)):
        area = areas[i]

        area_link = areas_link[i]
        # print(area_link)
        link = url+area_link
        print("当前区县:",area," ",link)
        get_pages(area, link)


#通过获取某一区域的页数,来拼接某一页的链接
def get_pages(area, area_link):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.125 Safari/537.36'}
    res = requests.get(area_link, headers=headers)
    content = html.fromstring(res.text)
    #链家新房页面统计每个区域的楼盘个数
    try:
        count = int(content.xpath('//div[@class ="page-box"]/@data-total-count')[0])
    except:
        print(count)
    #转换成页面,获取每个页面的楼盘信息
    if count%10 :
        pages = count//10+1
    else:
        pages = count//10
    print("这个区域有" + str(pages) + "页")

    for page in range(1, pages+1):
        url = area_link+'/pg' + str(page)
        print("开始抓取第" + str(page) +"页的信息")
        get_house_info(area, url)


#获取某一区域某一页的详细房租信息
def get_house_info(area, url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.125 Safari/537.36'}
    time.sleep(1+2*random.random()) # 间隔随机1-3秒避免访问太密集触发反扒机制
    try:
        # 获取页面信息
        print(url)
        res = requests.get(url, headers=headers)
        content = html.fromstring(res.text)
        data = []  # 构造一个列表存放当前页面所有楼盘详情
        for i in range(10): # 每页有10条楼盘信息
            try:
                # 获取楼盘详情:
                #获取编号
                project_id = content.xpath("//ul[@class='resblock-list-wrapper']/li/@data-project-name")[i]
                print(project_id,end=',')
                #详情页url
                detail_url = BASEURL+"p_"+project_id
                print(detail_url,end=',')
                # 获取标题
                title = content.xpath("//ul[@class='resblock-list-wrapper']/li/a/@title")[i]
                print(title,end=',')
                # 获取详细小区信息
                detail_area= content.xpath("//ul[@class='resblock-list-wrapper']/li//div[@class='resblock-location']/span[2]/text()")[i]
                print(detail_area,end=',')
                # 获取详细地址
                detail_place = content.xpath("//ul[@class='resblock-list-wrapper']/li//div[@class='resblock-location']/a/text()")[i]
                print(detail_place,end=',')
                # 获取小区类型
                type = content.xpath("//ul[@class='resblock-list-wrapper']/li//div[@class='resblock-name']/span[1]/text()")[i]
                print(type,end=',')
                sale_status = content.xpath("//ul[@class='resblock-list-wrapper']/li//div[@class='resblock-name']/span[2]/text()")[i]
                print(sale_status,end=',')
                # 获取面积
                try:
                    square = content.xpath("//ul[@class='resblock-list-wrapper']/li//div[@class='resblock-area']/span/text()")[i]
                except:
                    square = ""
                print(square,end=',')
                # 获取价格
                price = content.xpath("//ul[@class='resblock-list-wrapper']/li//div[@class='main-price']/span[1]/text()")[i]
                #价格待定的楼盘设置price为0
                if price=='价格待定':
                    price = None
                else:
                    price = int(price)
                print(price,end=',')
                #获取标签tag
                tag = content.xpath("/html/body/div[3]/ul[2]/li[{}]/div/div[5]/span/text()".format(i+1))
                print(tag,end='\n')
                
            except:
                break
            
            doc = {
                "project_id":project_id,
                "detail_url":detail_url,
                "area":area,
                "title":title,
                "detail_area":detail_area,
                "detail_place":detail_place,
                "type":type,
                "sale_status":sale_status,
                "square":square,
                "price":price,
                "tag":tag
            }    
            data.append(doc)
        save_data(data) #保存到mongodb中,该方法框架已写好,需要自己实现细节   
        print('continue the next page...')
    except:
        print(res.text)
        print(url)
        print('详情页面未获取成功,请手动查看页面是否需要人机验证!')
        time.sleep(30)
        

def save_data(data=None,host="127.0.0.1",port=27017,db_name="lianjia",col_name="loupan"):
   
    '''
    将解析到的楼盘详情数据存储到MongoDB数据库中
    :param data: 楼盘详情数据
    :param host: mongodb服务器地址
    :param port: mongodb服务端口
    :param db_name: mongodb数据库名称
    :param col_name: mongodb数据集合名称
    :return:
    '''
    #1.创建连接数据库对象
    #2.连接数据库
    #3.连接集合并实现插入
    
    pass

def main():
    print('开始!')
    # 重庆主站URL
    url = 'https://cq.fang.lianjia.com/loupan/'
    # 访问主站URL获取区县信息
    get_areas(url)
    
    

if __name__ == '__main__':
    main()
    

分析数据

  1. 分析各个区新楼盘的平均价格、房屋占比情况等等
    在这里插入图片描述
    在这里插入图片描述

问题

  1. 问题一
    没有相应的包,截图省略

解决方案:通过pip安装下面三个包即可

pip install requests
pip install lxml
pip install pymongo
  1. 问题二
    count = int(content.xpath(‘//div[@class =“page-box”]/@data-total-count’)[0])
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^
    IndexError: list index out of range
    在这里插入图片描述
    解决办法:打开对应的网页(https://cq.fang.lianjia.com/loupan/jiangbei)进行人机验证即可。这里是因为拿不到data-total-count值报错

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python+OpenCV 零基础学习笔记(4-5):计算机图形基础+Python相对文件路径+OpenCV图像+OpenCV视频

文章目录 相关链接运行环境前言计算机图形OpenCV简单使用图形读取文件读取可能会出现的问题:路径不对解决方案其它路径问题解决方案 图像显示保存OpenCV视频视频素材如何获取?简单视频读取 相关链接 【2022B站最好的OpenCV课程推荐】OpenCV从入门到实战 …

JavaSE基础50题:27(数组练习)二分查找

概述 给定一个有序整数数组,实现二分查找。 二分查找的前提:必须是有序的数组!! 方法具体实现 如找数字5,定义L、R、M,其中M是L和R的中间位置,即(LR) / 2 的位置。 如下图所示: ①…

小米SU7汽车发布会; 齐碳科技C+轮融资;网易 1 月 3 日发布子曰教育大模型;百度文心一言用户数已突破 1 亿

投融资 • 3200 家 VC 投资的创业公司破产,那个投 PLG 的 VC 宣布暂停投资了• 云天励飞参与 AI 技术与解决方案提供商智慧互通 Pre-IPO 轮融资• 百度投资 AIGC 公司必优科技• MicroLED量测公司点莘技术获数千万级融资• 智慧互通获AI上市公司云天励飞Pre-IPO轮战…

Redis布隆过滤器BloomFilter

👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家📕系列专栏:Spring源码、JUC源码、Kafka原理、分布式技术原理、数据库技术🔥如果感觉博主的文章还不错的…

【C语言】数据结构——排序(一)

💗个人主页💗 ⭐个人专栏——数据结构学习⭐ 💫点击关注🤩一起学习C语言💯💫 目录 导读:数组打印与交换1. 插入排序1.1 直接插入排序1.1.1 基本思想1.1.2 实现代码1.1.3 图解 1.2 希尔排序1.2.1…

Centos7:Jenkins+gitlab+node项目启动(3)

Centos7:Jenkinsgitlabnode项目启动(1) Centos7:Jenkinsgitlabnode项目启动(1)-CSDN博客 Centos7:Jenkinsgitlabnode项目启动(2) Centos7:Jenkinsgitlabnode项目启动(2)-CSDN博客 Centos7:Jenkinsgitlabnode项目启…

python如何读取被压缩的图像

读取压缩的图像数据: PackBits 压缩介绍: CCITT T.3 压缩介绍: 读取压缩的图像数据: 在做图像处理的时候,平时都是使用 函数io.imread() 或者是 函数cv2.imread( ) 函数来读取图像数据,很少用PIL.Image…

华为云CCE-集群内访问-根据ip访问同个pod

华为云CCE-集群内访问-根据ip访问同个pod 问题描述:架构如下:解决方法: 问题描述: 使用service集群内访问时,由于启用了两个pod,导致请求轮询在两个pod之间,无法返回正确的结果。 架构如下&am…

仪表盘、数据分析新增分享功能及应用服务下新增服务实例菜单

近期,博睿数据根据一体化智能可观测平台 Bonree ONE 产品本身,以及用户反馈进行持续的更新和优化。以下为 Bonree ONE 产品功能更新报告第03期内容,更多探索,未完待续。 本次迭代的更新集中在平台的仪表盘、数据分析新增分享功能&…

日志框架简介-Slf4j+Logback入门实践 | 京东云技术团队

前言 随着互联网和大数据的迅猛发展,分布式日志系统和日志分析系统已广泛应用,几乎所有应用程序都使用各种日志框架记录程序运行信息。因此,作为工程师,了解主流的日志记录框架非常重要。虽然应用程序的运行结果不受日志的有无影…

【ubuntu 22.04】安装中文版系统、中文语言包和中文输入法

在系统安装中的键盘布局选择时,选择Chinese - Chinese,此时会自动安装所有的中文语言包和ibus中文输入法系统安装成功重启后,点击设置 - 区域和语言 - 管理已安装的语言 * 根据提示安装更新后,将汉语(中国)…

springboot整合gateway网关

一、网关基本概念 1、API网关介绍 API 网关出现的原因是微服务架构的出现,不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题…

Python基础语法总结

1.每条语句结束不需要分号(也可以加上), 直接换行, 注意: 如果两行代码写一行, 则必须加分号. 2.定义变量不需要指定类型(如果需要写类型, 需要在变量名后面加": 类型, 这个写法只是方便读代码). 3.变量名大小写敏感. 4.查看变量类型: type(变量名). 5.Python中的int表…

AI-ChatGPTCopilot

ChatGPT chatGPT免费网站列表:GitHub - LiLittleCat/awesome-free-chatgpt: 🆓免费的 ChatGPT 镜像网站列表,持续更新。List of free ChatGPT mirror sites, continuously updated. Copilot 智能生成代码工具 安装步骤 - 登录 github&am…

硬件安全模块 (HSM)、硬件安全引擎 (HSE) 和安全硬件扩展 (SHE)的区别

术语 硬件安全模块 (HSM) :Hardware Security Modules硬件安全引擎 (HSE) :Hardware Security Engines安全硬件扩展 (SHE) : Secure Hardware Extensions 介绍 在汽车行业中,硬件安全模块 (HSM)、硬件安全引擎 (HSE) 和安全硬件…

MetalLB:本地Kubernetes集群的LoadBalancer负载均衡利器

背景 在本地集群进行测试时,我们常常面临一个棘手的问题:Service Type不支持LoadBalancer,而我们只能选择使用NodePort作为替代。这种情况下,我们通常会配置Service为NodePort,并使用externalIPs将流量导入Kubernetes…

论文阅读:Blind Super-Resolution Kernel Estimation using an Internal-GAN

这是发表在 2019 年 NIPS 上的一篇文章,那个时候还叫 NIPS,现在已经改名为 NeurIPS 了。文章中的其中一个作者 Michal Irani 是以色 Weizmann Institute of Science (魏茨曼科学研究学院) 的一名教授,对图像纹理的内在统计规律有着很深入的研…

【北亚服务器数据恢复】ZFS文件系统服务器ZPOOL下线的数据恢复案例

服务器数据恢复环境: 服务器中有32块硬盘,组建了3组RAIDZ,部分磁盘作为热备盘。zfs文件系统。 服务器故障: 服务器运行中突然崩溃,排除断电、进水、异常操作等外部因素。工作人员将服务器重启后发现无法进入操作系统。…

爬虫工作量由小到大的思维转变---<第三十三章 Scrapy Redis 23年8月5日后会遇到的bug)>

前言: 收到回复评论说,按照我之前文章写的: 爬虫工作量由小到大的思维转变---<第三十一章 Scrapy Redis 初启动/conn说明书)>-CSDN博客 在启动scrapy-redis后,往redis丢入url网址的时候遇到: TypeError: ExecutionEngine.crawl() got an unexpected …

.Net FrameWork总结

.Net FrameWork总结 介绍.Net公共语言运行库CLI的组成.NET Framework的主要组成.NET Framework的优点CLR在运行期管理程序的执行,包括以下内容CLR提供的服务FCL的组成 或 服务(这个其实就是我们编码时常用到的类库):(下…