python爬虫爬取安居客房源信息

Xpath插件的安装

链接:https://pan.baidu.com/s/1T3V11Ev8dPODa2fCRbeuCg
提取码:qvzf
在这里插入图片描述
将这个安装包解压缩
打开谷歌浏览器的扩展程序 ----> 打开开发者模式 ----> 点击加载已解压的扩展程序 ----> 选择解压的文件夹
看下图操作
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
就会出现这个
在这里插入图片描述
浏览器导航栏上也会出现X图标
在这里插入图片描述
点击图标就会弹出 再点击就会关闭(或者使用快捷键ctrl+shift+X) 会出现这样的黑框 左边写Xpath语法 右面是匹配到的结果 还可以看到匹配到的数量
在这里插入图片描述
需要自己去学习一下Xpath定位的语法 很简单的 这里就不赘述了

爬取重庆花溪附近的房源信息(进入正题啦~)

先看一下页面的样子,梳理下逻辑

列表页页面
在这里插入图片描述
列表页的分页按钮
在这里插入图片描述

详情页页面(点击列表页标题进入)
在这里插入图片描述

梳理下逻辑

我们先根据分页获得某一页的列表页,然后爬取列表页的房价,然后进入详情页,爬取详情页的下列信息
在这里插入图片描述
在这里插入图片描述

爬取数据的通用流程

  1. 根据url请求页面,获取页面响应对象(也就是下面代码中的html_obj = requests.get(url=url, headers=headers))
  2. 将页面响应对象转化为etree/parsel对象 (tree = etree.HTML(html_obj))
  3. 定位要爬取的数据 (tree.xpath(’…’))
  4. 获取数据
  5. 持久化存储

代码

终于到了心心念念,激动人心的时刻啦~~ 上代码!!!哈哈哈
写了注释了,不过多解释

from collections import defaultdict
import requests
import pandas as pd
from lxml import etree
import re

# 获取到分页url的一个统一格式
url_all = 'https://chongqing.anjuke.com/sale/p{}-rd1/?kw=%E8%8A%B1%E6%BA%AA#filtersort'
# 请求头
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
}

def get_url_list(url):
    '''获取url列表  用于分页获取内容'''
    url_list = [url.format(i) for i in range(1, 21)] # 获取20页
    return url_list

def get_page_etree(url, headers):
    '''得到页面的etree对象'''
    html_obj = requests.get(url=url, headers=headers)# 根据url请求页面,获取页面响应对象html_obj
    html_obj = html_obj.content.decode() # 解决乱码问题
    tree = etree.HTML(html_obj) # 转化为页面的etree对象
    return tree

def get_data(tree):
    """获取一页的房子数据"""

    # 建立字典
    info_dicts = defaultdict(list)

    # 定位到一页列表页的所有li标签
    li_list = tree.xpath('//ul[@id="houselist-mod-new"]/li')
    for li in li_list:  # 遍历每一条(li标签) 一个li就对应着一个房子 一个房子的数据全部爬取完再爬取下一个房子,一页爬取完再爬下一页
        # 列表页 获取价格
        jiage = li.xpath('./div[@class="pro-price"]//strong/text()')[0]
        info_dicts['价格(万)'].append(jiage)

        # 接下来进入详情页 获取其他数据
        # 先获取a链接href属性值 再跳转到该链接进行爬取
        a = li.xpath('.//div[@class="house-title"]/a/@href')[0]
        # 获取详情页etree对象
        tree_i = get_page_etree(url=a, headers=headers)
        # 解析数据
        hx = tree_i.xpath('//ul[@class="houseInfo-detail-list clearfix"]/li[2]/div[2]/text()')[0].strip().split()
        info_dicts['户型-房间'].append(hx[0])
        info_dicts['户型-厅'].append(hx[1])
        info_dicts['户型-卫生'].append(hx[2])
        # 建筑面积
        mj = tree_i.xpath('//ul[@class="houseInfo-detail-list clearfix"]/li[5]/div[2]/text()')[0]
        info_dicts['建筑面积'].append(mj)
        # 朝向
        cx = tree_i.xpath('//ul[@class="houseInfo-detail-list clearfix"]/li[8]/div[2]/text()')[0]
        info_dicts['朝向'].append(cx)
        # 小区
        xq = tree_i.xpath('//ul[@class="houseInfo-detail-list clearfix"]/li[1]/div[2]/a/text()')[0].strip()
        info_dicts['小区'].append(xq)
        # 地址
        dz = tree_i.xpath('//ul[@class="houseInfo-detail-list clearfix"]/li[4]/div[2]/p/text()')[1].strip().split()[1]
        info_dicts['地址'].append(dz)
        # 建筑时间
        jzsj = tree_i.xpath('//ul[@class="houseInfo-detail-list clearfix"]/li[7]/div[2]/text()')[0].strip()
        info_dicts['建筑时间'].append(jzsj)
        # 总楼层  所处层数
        str = tree_i.xpath('//ul[@class="houseInfo-detail-list clearfix"]/li[11]/div[2]/text()')[0]
        zlc = re.search(r'\d+', str, re.A).group() # 这里用到了正则表达式提取信息
        info_dicts['总楼层'].append(zlc)
        cs = re.search(r"['高','中','低']", str, re.U)
        if cs is None:
            cs = ''
        else:
            cs = cs.group()
        info_dicts['所处层数'].append(cs)
        # 装修
        zx = tree_i.xpath('//ul[@class="houseInfo-detail-list clearfix"]/li[12]/div[2]/text()')[0]
        info_dicts['装修'].append(zx)
        # 电梯
        dt = tree_i.xpath('//ul[@class="houseInfo-detail-list clearfix"]/li[14]/div[2]/text()')[0]
        info_dicts['电梯'].append(dt)

    data = pd.DataFrame(info_dicts)
    return data


# 主程序部分
data = pd.DataFrame()
# 获取url列表 用于分页爬取
url_list = get_url_list(url_all)
for i, url in enumerate(url_list):
    # 获取每一页的列表页etree对象
    tree = get_page_etree(url=url,headers=headers)
    # 得到所有数据追加到data中
    data = data.append(get_data(tree),ignore_index=True)
    print('第',i+1,'页爬取成功!')
# 持久化存储
data.to_excel('重庆花溪房源数据.xls')


请求头

headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
}

这里从这里找,复制 粘贴它
在这里插入图片描述

代码的问题 & 运行时可能出现的问题

存数据是爬到所有数据一次从DataFrame存到excel里,如果数据太大可能内存会吃不消,可以自己尝试下一页一追加到excel里,我这个20页(页数可以改的哈)1200条数据也还可以,数据量不大

如果报错就从网页手动访问页面,看是不是被人家的系统检测到你爬取了,就像下面这样 就换个网 刷新下页面能访问到列表页 再运行程序爬取
在这里插入图片描述

或者可能会出现验证码,手动通过验证码 ,刷新页面,再爬取就ok
建议多刷新下页面试试,能手动的访问到列表页一般就能正常爬下数据来

结果

在这里插入图片描述
(电梯那一栏 有“满三年”值 是因为 不是所有房子的详情页的是否有电梯那个数据都在同一位置上,他那个格式不是很统一,就会爬错)

爬虫学习视频推荐,我从B站这个视频学了学,觉得不错附上链接
https://www.bilibili.com/video/BV1Yh411o7Sz?t=825&p=25
xpath语法讲挺好的视频:https://www.bilibili.com/video/BV14K411L7T5 (就是打广告有点多~~)

加油,你是最胖的,欧耶~~

转载请附上我的链接哦~
欢迎点赞+转发+评论+讨论~~
感谢支持~

数据处理部分(写给我自己哒~)

import pandas as pd

data = pd.read_excel(r'C:/Users/user/Desktop/housePrice.xls')

# 处理缺失值
data = data.dropna(axis=0,subset=['所处层数'])

# 处理 电梯 异常值
data = data[data['电梯']!='满三年']

# 字符型改成数值型数据
# 小区
xq = data['小区'].unique()
xq_dict = {value:key for key, value in enumerate(xq)}
print(xq_dict)
data['小区'] = [xq_dict[i] for i in data['小区']]


# 朝向
cx = data['朝向'].unique()
cx_dict = {value:key for key, value in enumerate(cx)}
print(cx_dict)
data['朝向'] = [cx_dict[i] for i in data['朝向']]

# 地址
dz = data['地址'].unique()
dz_dict = {value:key for key, value in enumerate(dz)}
print(dz_dict)
data['地址'] = [dz_dict[i] for i in data['地址']]

# 所处层数
cs = data['所处层数'].unique()
cs_dict = {value:key for key, value in enumerate(cs)}
print(cs_dict)
data['所处层数'] = [cs_dict[i] for i in data['所处层数']]

# 装修
zx = data['装修'].unique()
zx_dict = {value:key for key, value in enumerate(zx)}
print(zx_dict)
data['装修'] = [zx_dict[i] for i in data['装修']]

# 电梯
dt = data['电梯'].unique()
dt_dict = {value:key for key, value in enumerate(dt)}
print(dt_dict)
data['电梯'] = [dt_dict[i] for i in data['电梯']]


data.to_excel('housePrice.xlsx')
# print(data)

{‘溪山玥’: 0, ‘申烨太阳城’: 1, ‘日月山庄’: 2, ‘宗申动力城’: 3, ‘碧桂园渝南首府’: 4, ‘宗申青年国际’: 5, ‘浣溪锦云’: 6, ‘华润澜山望’: 7, ‘东原桐麓’: 8, ‘芸峰兰亭’: 9, ‘东海定南山’: 10, ‘曦圆丽景’: 11, ‘保利林语溪’: 12, ‘蔚蓝时光’: 13}
{‘南’: 0, ‘南北’: 1, ‘东南’: 2, ‘北’: 3, ‘东’: 4, ‘西南’: 5, ‘东北’: 6, ‘西北’: 7, ‘西’: 8}
{‘渝南分流道’: 0, ‘渝南大道158号附45号’: 1, ‘渝南大道118号’: 2, ‘渝南大道130号’: 3, ‘渝南大道91号’: 4, ‘渝南大道158号’: 5, ‘渝南大道129号’: 6, ‘龙鸣路’: 7, ‘渝南大道123号’: 8, ‘龙洲大道1958号’: 9, ‘渝南大道115号’: 10, ‘青龙湾路’: 11, ‘渝南大道9号’: 12, ‘渝南大道8号’: 13}
{‘中’: 0, ‘低’: 1, ‘高’: 2}
{‘毛坯’: 0, ‘精装修’: 1, ‘简单装修’: 2, ‘豪华装修’: 3}
{‘有’: 0, ‘无’: 1}

  • 19
    点赞
  • 120
    收藏
    觉得还不错? 一键收藏
  • 20
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值