数据采集课设—链家家居爬取

大据采集与预处理课程设计任务书

  1. 数据采集与预处理的概述

要求:引言的作用,要以自己后面使用的内容分为中心简述。

2、XXX为基础的相关技术介绍

要求:

  1. 数据采集、预处理选择的技术或库选择介绍。要求具体到选用开发工具、库函数的介绍、API参数设置等,在数据预处理部分可有预处理方法选择的原由、针对同一类型预处理多种选择方法的对比分析。
  2. 文中引用内容用上标标注参考文献的引用

3、XXX数据爬取、预处理的分析设计与实现

要求:

      1.  原始网站数据出现的界面,预爬取数据的编程分析过程及关键结果的描述,包括爬取数据的URL、参数、定位信息、爬取时用到的header等,表述形式:截图+说明文字。
      2. 包括主要功能模块设计和介绍,数据存储方式和数据所含数据项的描述。
      3. 软件组成介绍:软件模块的项目结构截图或软件文件的资源管理器截图,并附文字介绍。以功能模块为切入点介绍具体的实现,针对功能模块附加必要的文字注释、解释、主要代码、运行界面和遇到的问题及对应的解决方法。
  1. 总结

主要介绍收获、心得体会、个人的展望、实现的完善方向等。

5、参考文献

目录

第一章 数据采集与预处理概述

1.1 背景介绍

1.2 技术介绍

第二章 requests和lxml库为基础的相关技术和应用分析

2.1原始网站界面数据的介绍

2.2预爬取的数据及其描述

2.3获取xpath路径

2.4相关技术和库选择介绍

第三章 链家房屋数据爬取、预处理的实现

3.1链家房屋数据爬取的实现

3.2链家家房屋数据预处理的实现

3.4运行的结果

第四章 总结

第五章 参考文献

附 录

(1) 链家家屋数据爬取代码

(2) 链家家居数据预处理代码

(3) gui总代码

第一章 数据采集与预处理概述

1.1 背景介绍

通过了解芜湖市二手房的情况,可以帮助人们在购房、出租等方面做出更明智的决策。随着互联网的发展,越来越多的房地产信息通过网络发布,使用爬虫技术可以方便地收集和分析这些信息。

本次数据采集与预处理课程设计选择的数据来源是链家。链家是一家著名的房地产经纪公司,在芜湖市有着广泛的房地产业务。通过爬取芜湖市链家发布的二手房房信息,可以获得丰富的数据,为分析提供参考。

链家官网提供的数据包括二手房房源基本信息、房源描述、价格情况、中介服务等相关内容,以及用户留言反馈等信息。这些数据采用爬虫技术获取,在选择爬虫方式时,可以使用多种方式对数据进行筛选,通过对数据的筛选,从而获得更全面、准确的数据,得到我们需要的信息。

1.2 技术介绍

本次课程以链家网房源信息为例,爬取链家网二手房的房源信息相关,爬取完房源信息相关数据之后,对房源信息数据进行预处理,进行删除重复值,调整数据表格格式等一系列数据预处理操作,保证数据的准确性。在对链家网房源信息数据采集与预处理之后,对房源信息数据进行数据可视化相关操作,分析影响房价的一些因素,尝试画出了这些因素与房价的分布情况。

第二章 requests和lxml库为基础的相关技术和应用分析

2.1原始网站界面数据的介绍

① 原始网站页面

  

注意:

在原始网站界面可以观察到URL:芜湖二手房房源_芜湖二手房出售|买卖|交易信息(芜湖链家)

其中:wuhu是爬取城市的拼写

      ershoufang:是爬取的房源类型拼写

 当原始网站页面翻到了第二页时,URL发生了变化

  

注意:

URL:https://wuhu.lianjia.com/ershoufang/pg2/

可见界面换页操作是通过pg进行控制的

 观察请求方法与User-Agent

请求方法:get

User-Agent:

 

2.2预爬取的数据及其描述

以页面第一个房源信息——翡丽世家叠墅为例

 

要爬取的数据有:

①楼房简介

②楼房地点

③楼房信息(户型,面积,朝向,装修,楼层,结构)

④楼房价格

⑤楼房单价

2.3获取xpath路径

以翡丽世家叠墅为例。右键所选网页字段,选择检查,找到字段在源代码中的位置,右键选择复制选项栏中复制为完整的xpath路径

(1)楼房简介

xpath路径://*[@id="content"]/div[1]/ul/li[1]/div[1]/div[1]/a

(2)楼盘地点

需要获取两个部分的内容,分别位于div标签下的两个a标签中

xpath路径:① //*[@id="content"]/div[1]/ul/li[1]/div[1]/div[2]/div/a[1]

               ② //*[@id="content"]/div[1]/ul/li[1]/div[1]/div[2]/div/a[2]

(3)楼房信息

获取的楼房信息数据是以“|”为间隔的,后面进行数据预处理操作时,需要把楼房信息数据中的各个数据以间隔符“|”分开。

xpath路径://*[@id="content"]/div[1]/ul/li[1]/div[1]/div[3]/div

(4)楼房价格

总价 xpath路径://*[@id="content"]/div[1]/ul/li[1]/div[1]/div[6]/div[1]/span

单价 xpath路径://*[@id="content"]/div[1]/ul/li[1]/div[1]/div[6]/div[2]/span

2.4相关技术和库选择介绍

(1)开发平台:PyCharm Community Edition 2022.3.2

Pycharm是一种Python IDE(Integrated Development Enviroment,集成开发环境),带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具,比如调试、语法高亮、项目管理、代码跳转、智能提示 、自动完成、单元测试、版本控制。此外,该IDE提供了一些高级功能,以用于支持Django框架下的专业web开发。此次,以链家家房源数据为基础的数据采集和预处理就是Pycharm开发环境下运行的。

(2)库选择介绍:requests库、openpyxl库、lxml库、pandas库、tkinter库、os库、messagebox库。

  • tkinter: 用于创建 GUI 界面,包括窗口、标签、按钮等。tkinter 负责创建用户界面,让用户输入要爬取的页面数量;
  • requests库: 用于发送 HTTP 请求,获取网页内容。requests 发送网络请求获取网页内容;
  • lxml库: 用于解析 HTML 和 XML 文档,提取所需数据。lxml 解析网页内容提取所需数据;
  • pandas库: 用于数据处理和分析,将爬取的数据存储到 DataFrame 中并进行预处理。pandas 将数据存储到 DataFrame 中并进行预处理;
  • os库: 用于操作文件路径,获取桌面路径和创建 Excel 文件。os 获取桌面路径并创建 Excel 文件;
  • openpyxl库: 用于读写 Excel 文件,对 Excel 文件进行格式调整。openpyxl 读取 Excel 文件并调整格式;
  • messagebox库: 用于创建消息框,显示提示信息和错误信息。

(3)函数介绍:fetch_data_and_preprocess(pages)、start_scraping_and_preprocessing()、pd.read_excel()、DataFrame.drop_duplicates()、DataFrame.isnull().values.any()等

  • pd.read_excel():读取 Excel 文件并将其转换为 pandas 的 DataFrame。
  • DataFrame.drop_duplicates():去除 DataFrame 中重复的行。
  • DataFrame.map():根据提供的映射将 DataFrame 中的某一列的值转换为其他值。
  • DataFrame.isnull().values.any():检查 DataFrame 中是否存在空值,并返回结果。
  • to_excel():将 DataFrame 写入 Excel 文件。
  • load_workbook():加载一个已存在的 Excel 文件。
  • Alignment(horizontal='center', vertical='center'):设置单元格文本的水平和垂直对齐方式。
  • Font(bold=True):定义单元格文本的字体样式。
  • wb.save():保存对 Excel 文件的修改。
  • fetch_data_and_preprocess(pages) :从链家网站爬取指定数量的页面数据,并进行预处理。
  • start_scraping_and_preprocessing():从 GUI 中获取用户输入的页面数量,并调用 fetch_data_and_preprocess(pages) 函数进行数据爬取和处理。如果用户输入的不是有效的页数,则弹出错误提示。

2.5数据预处理过程

数据预处理的方法有:1.数据清理,通过填写缺失的值,光滑噪声数据,识别或删除离群点并解决不一致性来“清理”数据;2.数据集成,将多个数据源中的数据结合起来并统一存储,建立数据仓库的过程实际上就是数据集成;3.数据变换;4.数据归约。

  1. 查看列名,删除不相关列

其中‘楼房简介’并不是用户买二手房的决定性因素,需要删除。

  1. 查看是否有重复行

在去除楼房简介之前先根据楼房简介来删除重复行,相对于其他的来说数据更加准确。

  1. 查看是否有空值

  1. 非数值列数值化

楼房结构共有板楼、板塔结合、暂无数据、塔楼三种。

用1表示板楼,2表示板塔结合,0表示暂无数据,3表示塔楼。

对于楼房结构列数值化

添加楼房结构化说明方便对照

第三章 链家房屋数据爬取、预处理的实现

3.1链家房屋数据爬取的实现

(1)导入相关库

Gui总

芜湖链家家居数据爬取

(2)向网页发送请求

① URL的确定

由于要连续爬取多个页面的房源信息数据,所以用利用循环语句去改变URL。

我们可以通过改变pg参数来改变不同页面的URL,实现连续多页爬取

url = f'https://wuhu.lianjia.com/ershoufang/pg{i}'

② 确定请求方法

    

向网页发送get请求,并将请求结果赋给response

(3)解析页面数据

爬取的数据有楼房简介、楼房位置、楼房户型、楼房面积、楼房朝向、楼房装修、楼房楼层、楼房结构、楼房价格、楼房单价。

# 解析数据

div_list = data.xpath('//div[@class="info clear"]')

for div in div_list:

    # 爬取标题信息

    title = div.xpath('.//div[@class="title"]/a/text()')[0]

    title_list.append(title)

    # 爬取位置信息

    positionInfo1 = div.xpath('.//div[@class="flood"]/div/a[1]/text()')[0]

    positionInfo2 = div.xpath('.//div[@class="flood"]/div/a[2]/text()')[0]

    positionInfo = positionInfo1 + positionInfo2

    positionInfo_list.append(positionInfo)

    # 爬取房源信息

    houseInfo = div.xpath('.//div[@class="address"]/div/text()')[0]

    houseInfo_list = houseInfo.split('|')

    a = houseInfo_list[0].strip()

    a_list.append(a)

    b = houseInfo_list[1].strip('平米')

    b_list.append(b)

    c = houseInfo_list[2].strip()

    c_list.append(c)

    d = houseInfo_list[3].strip()

    d_list.append(d)

    e = houseInfo_list[4].strip()

    e_list.append(e)

    f = houseInfo_list[5].strip()

    f_list.append(f)

    # 爬取价格信息

    priceInfo = div.xpath('.//div[@class="priceInfo"]/div[1]/span/text()')[0]

    priceInfo_list.append(priceInfo)

    unitInfo = div.xpath('.//div[@class="priceInfo"]/div[2]/span/text()')[0].strip('/')  # 爬取房源的标签单价

    unitInfo_list.append(unitInfo)

(4)存储数据

# 存储数据

name = ["楼房简介", "楼房位置", "楼房户型", "楼房面积(平米)", "楼房朝向", "楼房装修", "楼房楼层", "楼房结构",

        "楼房价格(万/套)", "楼房单价(元/)"]

housedata = pd.DataFrame(

    zip(title_list, positionInfo_list, a_list, b_list, c_list, d_list, e_list, f_list, priceInfo_list,

        unitInfo_list), columns=name)

3.2链家家房屋数据预处理的实现

数据预处理部分

# 去除重复行

housedata.drop_duplicates(subset=['楼房简介'], inplace=True)

# 去除"楼房简介"列

housedata.drop(columns=['楼房简介'], inplace=True)

# 检查空值

null_count = housedata.isnull().sum().sum()

if null_count > 0:

   messagebox.showerror("错误", f"数据中存在 {null_count} 个空值,请处理后重新运行")

    return

else:

    print("数据中不存在空值")

# 楼房结构映射

structure_mapping = {

    '板楼': 1,

    '板塔结合': 2,

    '暂无数据': 0,

    '塔楼': 3

}

# 映射楼房结构

housedata['楼房结构'] = housedata['楼房结构'].map(structure_mapping)

# 创建预处理后的Excel文件

desktop_path = os.path.expanduser("~/Desktop")

preprocessed_file_path = os.path.join(desktop_path, "芜湖二手房(预处理完成).xlsx")

housedata.to_excel(preprocessed_file_path, index=False, engine='openpyxl')

# 加载新创建的Excel文件并调整格式

wb = load_workbook(preprocessed_file_path)

ws = wb.active

# 设置列宽和居中对齐

for col in ws.columns:

    max_length = 0

    column = col[0].column_letter

    for cell in col:

        try:

            if len(str(cell.value)) > max_length:

                max_length = len(str(cell.value))

        except:

            pass

        cell.alignment = Alignment(horizontal='center', vertical='center')

    # 单独处理楼房简介和楼房位置列,增加更多宽度

    if col[0].value == '楼房简介' or col[0].value == '楼房位置':

        adjusted_width = (max_length + 2) * 1.9  # 增加更多宽度

    else:

        adjusted_width = (max_length + 2) * 1.5  # 其他列适度增加宽度

    ws.column_dimensions[column].width = adjusted_width

    # 添加楼房结构说明

    structure_notes = ['暂无数据', '板楼', '板塔结合', '塔楼']

    structure_values = [0, 1, 2, 3]

    structure_col = len(ws['A']) + 2  # 楼房结构说明列在原数据右侧

    structure_col = len(ws['A']) + 2 - 21

    for i, (note, value) in enumerate(zip(structure_notes, structure_values)):

        note_cell = ws.cell(row=i + 1, column=structure_col, value=note)

        value_cell = ws.cell(row=i + 1, column=structure_col + 1, value=value)

        note_cell.alignment = Alignment(horizontal='center', vertical='center')  # 居中对齐

        value_cell.alignment = Alignment(horizontal='center', vertical='center')  # 居中对齐

        # 添加边框和设置字体

        thin_border = Border(left=Side(style='thin'), right=Side(style='thin'), top=Side(style='thin'),

                             bottom=Side(style='thin'))

        note_cell.border = thin_border

        value_cell.border = thin_border

        note_cell.font = Font(bold=True)

(4)输出数据并保存数据

#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值