赞
踩
最近房地产市场进一步收紧,多地地方政府出台各种收紧政策,以保证房地产健康发展,因此云朵君就想到运用Python网络爬虫,抓取部分房产信息,了解下最近房地产的情况。
接下来以房天下二手房信息,以获取某个城市各个区域二手房房产信息急价格,来一起学习下Python网络爬虫的基本方法。
备注,本文仅以学习交流,对于爬虫浅尝辄止,以免对服务器增加负担。
运用谷歌浏览器开发者工具分析网站
# 各区域网站地址如下规律
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
可以循环获取。
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
。
由于每个行政区域及其各页数据可重复循环获取,因此这里只介绍一个区域(青羊区)的第一页。
分析每条数据所存在的地方。
查看每个信息所在的节点。
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'
其余部分只需要循环获取即可。
import pandas as pd
data = pd.read_csv("成都二手房_青羊.csv")
data.sample(5)
本次获取一个行政区共6027个二手房信息。
data.shape
>>> (6027, 13)
由于此网站监控较为严格,可利用selenium模拟浏览器一定程度上规避反爬机制。
分析网页的方法同上,但此次并不是循环请求网页获取网页数据,而是通过模拟浏览器操作,再通过Xpath获取数据。
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路径获取数据。
content_list = browser.find_elements_by_xpath("//div[@class='shop_list shop_list_4']/dl")
content_list
得到以 WebElement对象
为元素的列表。
可通过遍历的方法遍历获取。
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
其中一天信息如下。
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
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
原文链接:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。