前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >运用Python抓取二手房价格与信息的两种常用方法

运用Python抓取二手房价格与信息的两种常用方法

作者头像
数据STUDIO
发布2021-06-24 11:09:16
5490
发布2021-06-24 11:09:16
举报
文章被收录于专栏:数据STUDIO

最近房地产市场进一步收紧,多地地方政府出台各种收紧政策,以保证房地产健康发展,因此云朵君就想到运用Python网络爬虫,抓取部分房产信息,了解下最近房地产的情况。

接下来以房天下二手房信息,以获取某个城市各个区域二手房房产信息及价格,来一起学习下Python网络爬虫的基本方法。

备注,本文仅以学习交流,对于爬虫浅尝辄止,以免对服务器增加负担。

一、BeautifulSoup解析数据

分析网站

运用谷歌浏览器开发者工具分析网站

代码语言:javascript
复制
# 各区域网站地址如下规律
https://cd.esf.fang.com/house-a0129/
https://cd.esf.fang.com/house-a0130/
https://cd.esf.fang.com/house-a0132/

# 每个区域不同页的网址规律
https://cd.esf.fang.com/house-a0132/i32/
https://cd.esf.fang.com/house-a0132/i33/
https://cd.esf.fang.com/house-a0132/i34/

# 因此可定义网址形式如下
base_url = 'https://cd.esf.fang.com{}'.format(region_href)
tail_url = 'i3{}/'.format(page)
url = base_url + tail_url

网址获取

接下来重点获取region_href, page可以循环获取。

HTML中找到所有区域及region_href

代码
代码语言:javascript
复制
from requests_html import UserAgent
import requests
from bs4 import BeautifulSoup
user_agent = UserAgent().random
url = 'https://cd.esf.fang.com/'
res = requests.get(url, headers={"User-Agent": user_agent})
soup = BeautifulSoup(res.text, features='lxml')  # 对html进行解析,完成初始化
results = soup.find_all(attrs={'class': "clearfix choose_screen floatl"})
regions = results[0].find_all(name='a')
region_href_list = []
region_name_list = []
for region in regions:
    region_href_list.append(region['href'])
    region_name_list.append(region.text)

本次使用BeautifulSoup解析网页数据,获取region_href及对应行政区域名称region_name。 可以参考《Beautiful Soup解析数据模块》

获取数据

宏观分析

由于每个行政区域及其各页数据可重复循环获取,因此这里只介绍一个区域(青羊区)的第一页。

分析每条数据所存在的地方。

微观分析

查看每个信息所在的节点。

代码
代码语言:javascript
复制
import re
regex = re.compile('\s(\S+)\s')
results = soup.find_all(attrs={'class': 'clearfix', 'dataflag': "bg"})
result = results
content = result.dd

# 获取项目简述
title = regex.findall(content.h4.a.text)
','.join(title)
>>> '精装修套三,视野好'

# 获取项目名称与地址
name = regex.findall(content.find_all(name='p', attrs={'class': 'add_shop'})[0].text)[0]
address = regex.findall(content.find_all(name='p', attrs={'class': 'add_shop'})[0].text)[1]
name
>>> '成都花园上城'
address
>>> '贝森-成都花园上城家园南街1号'

# 获取项目描述,包括户型、区域、楼层、朝向、建筑年代
describe = regex.findall(content.find_all(name='p', attrs={'class': 'tel_shop'})[0].text)
describe
>>> ['3室2厅', '|', '141.26㎡', '|', '中层(共22层)', '|', '西向', '|', '2008年建', '|', '杨斌']

# 获取优势标签
labels = regex.findall(content.find_all(name='p', attrs={'class': 'clearfix label'})[0].text)
labels
>>> ['距7号线东坡路站约830米']

# 获取价格
prices = result.find_all(name='dd', attrs={'class': 'price_right'})[0].text
prices
>>> '\n\n380万\n26900元/㎡\n'

其余部分只需要循环获取即可。

结果

代码语言:javascript
复制
import pandas as pd
data = pd.read_csv("成都二手房_青羊.csv")
data.sample(5)

本次获取一个行政区共6027个二手房信息。

代码语言:javascript
复制
data.shape
>>> (6027, 13)

Selenium模拟浏览器

由于此网站监控较为严格,可利用selenium模拟浏览器一定程度上规避反爬机制。 可参考《selenium 爬取动态加载信息》

分析网页的方法同上,但此次并不是循环请求网页获取网页数据,而是通过模拟浏览器操作,再通过Xpath获取数据。 可参考《XPath解析》

导入并初始化浏览器驱动

代码语言:javascript
复制
import requests
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
import time
from requests_html import UserAgent
from openpyxl import Workbook
import os
import json
import numpy as np

def init():
    """
    初始化谷歌浏览器驱动
    :return:
    """
    chrome_options = webdriver.ChromeOptions()
    # 不加载图片
    prefs = {"profile.managed_default_content_setting.images": 2}
    chrome_options.add_experimental_option("prefs", prefs)

    # 使用headless无界面浏览模式
    chrome_options.add_argument('--headless')
    chrome_options.add_argument('--disable-gpu')

    # 加载谷歌浏览器驱动
    browser = webdriver.Chrome(options=chrome_options,
                               executable_path='chromedriver.exe')
    browser.get('https://cd.esf.fang.com/')
    wait = WebDriverWait(browser, 10)  # 最多等待十秒
    wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'screen_al')))

    return browser

获取数据

按页获取数据

此方法是根据xpath路径获取数据。

代码语言:javascript
复制
content_list = browser.find_elements_by_xpath("//div[@class='shop_list shop_list_4']/dl")
content_list

得到以 WebElement对象为元素的列表。

可通过遍历的方法遍历获取。

代码语言:javascript
复制
content = content_list[0]
describe = content.find_elements_by_xpath('dd')[0].text
price = content.find_elements_by_xpath('dd')[1].text
row = [describe, price, city]
row

其中一天信息如下。

代码
代码语言:javascript
复制
def get_page_content(browser, sheet, region):
    """
    按页获取每页内容
    :param browser: 浏览器驱动
    :param sheet: excel 工作表
    :param region: 行政区域名称
    :return:
    """
    content_list = browser.find_elements_by_xpath("//div[@class='shop_list shop_list_4']/dl")
    for content in content_list:
        try:
            describe = content.find_elements_by_xpath('dd')[0].text
            price = content.find_elements_by_xpath('dd')[1].text
            row = [describe, price, region]
            sheet.append(row)
        except:
            pass
    return browser, sheet
按行政区获取数据
代码语言:javascript
复制
def get_region_content(browser, href, sheet, region):
    """
    获取行政区域内容
    :param browser:谷歌浏览器驱动
    :param href: 请求地址
    :param sheet: excel 工作表
    :param region: 行政区域
    :return:
    """
    print(f'正在爬取{region}区'.center(50, '*'))
    browser.find_element_by_xpath(f"//a[@href='{href}']").click()
    # 滑动到浏览器底部,已保证全部加载完成
    browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')
    time.sleep(2)
    # 重新滑动到浏览器顶部
    browser.execute_script('window.scrollTo(0,0)')
    wait = WebDriverWait(browser, 15)  # 最多等待十秒
    wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'page_box')))

    browser, sheet = get_page_content(browser, sheet, region)
    time.sleep(np.random.randint(10, 15))
    # 按页获取每一页的内容
    for page in range(2, 101):
        print(f'正在爬取{region}区的第{page}页'.center(30, '-'))
        try:
            browser.find_element_by_xpath(f"//a[@href='{href}i3{page}/']").click()
            browser, sheet = get_page_content(browser, sheet, region)
            time.sleep(np.random.randint(14, 15))
        except:
            break
    return browser, sheet
综合获取数据
代码语言:javascript
复制
def get_content():
    region_href_list, region_name_list = get_href_list()
    for ind, href in enumerate(region_href_list):
        browser = init()

        region = region_name_list[ind]
        wb = Workbook()
        sheet = wb.active
        sheet.title = region
        header = ['描述', '价格', '行政区']
        sheet.append(header)
        browser, sheet = get_region_content(browser, href, sheet, region)
        wb.save(f'{region}.xlsx')
        print(f'{region}.xlsx已经存储完毕'.center(60, '#'))

        time.sleep(np.random.randint(15, 20))
        browser.quit()

结果

获取数据后,可以对数据清洗并分析。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-03-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据STUDIO 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、BeautifulSoup解析数据
    • 分析网站
      • 网址获取
        • 代码
      • 获取数据
        • 宏观分析
        • 微观分析
        • 代码
      • 结果
      • Selenium模拟浏览器
        • 导入并初始化浏览器驱动
          • 获取数据
            • 按页获取数据
            • 代码
            • 按行政区获取数据
            • 综合获取数据
          • 结果
          相关产品与服务
          云拨测
          云拨测(Cloud Automated Testing,CAT)利用分布于全球的监测网络,以真实终端用户使用场景为视角,提供模拟终端用户体验的拨测服务。CAT 可实现对网络质量、页面性能、端口性能、文件传输、音视频体验等场景进行周期性监控,支持多维度分析性能指标。利用可视化性能数据和告警通知可帮助您及时对业务质量作出反应,保证业务稳定正常运行。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档