从链家网爬取指定城市的二手房信息,并将数据保存为CSV文件。它使用了Selenium库来模拟浏览器行为,以便获取动态加载的页面内容。具体而言,它实现了一个名为LianJia的类,其中包含了获取房源列表和房源详情的方法。主要步骤如下:
- 读取城市信息和代理IP信息,并初始化Chrome浏览器及其设置。
- 定义LianJia类,其中house_list()方法用于获取指定城区的所有房源链接,house_detail()方法用于获取单个房源的详细信息。
- run()方法用于执行爬取过程,它首先访问链家网站,然后获取指定城市的所有城区链接,再依次遍历每个城区,获取所有房源的详细信息,并保存到CSV文件中。
- 最后,循环遍历所有城市,调用run()方法执行爬取任务。
- 需要注意的是,这段代码在使用Selenium时需要确保已经安装好Chrome浏览器和对应版本的ChromeDriver,并将ChromeDriver的路径添加到系统环境变量中。
from selenium import webdriver
from fake_useragent import UserAgent
import random
from selenium.webdriver.common.by import By
import os
import pandas as pd
from pinyin import pinyin
import subprocess
# 读取城市信息
with open("city.txt", "r", encoding="utf-8") as file:
cities = [line.strip() for line in file if line.strip()]
ips = []
with open('ip.txt', 'r') as f:
for line in f:
ip = line.strip()
ips.append(ip.strip())
# 启动Chrome浏览器调试服务
subprocess.Popen('cmd', shell=True)
subprocess.Popen('chrome-win64\chrome.exe" --remote-debugging-port=9222', shell=True)
chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option("debuggerAddress", "localhost:9222")
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable‐gpu')
chrome_options.add_argument("--disable-blink-features=AutomationControlled")
chrome_options.add_argument('--proxy-server=http://' + random.choice(ips))
chrome_options.add_argument(f"user-agent={UserAgent().random}")
driver = webdriver.Chrome(options=chrome_options)
class LianJia:
def __init__(self):
# 声明Chrome浏览器对象, 这里填写你自己的driver路径
self.driver = driver
self.item = None
def house_detail(self, item):
"""获取一间房子的详情信息"""
self.driver.get(item['houseURL']) # 访问一间房子的详情页
# 获取页面上的房子信息
item['title'] = self.driver.find_element(By.TAG_NAME, 'h1').text # 标题
item['price'] = self.driver.find_element(By.CSS_SELECTOR, 'span.total').text # 价格
house_info = self.driver.find_elements(By.CSS_SELECTOR, 'div.mainInfo')
item['room'] = house_info[0].text # 户型
item['faceTo'] = house_info[1].text # 朝向
item['area'] = house_info[2].text # 面积
# 小区名
item['communityName'] = self.driver.find_element(By.CSS_SELECTOR, 'div.communityName a.info').text
# 发布日期
item['releaseDate'] = self.driver.find_element(By.XPATH, '//div[@class="transaction"]/div[2]/ul/li/span[2]').text
def house_list(self, item):
"""获取一个城区中所有房子的详情页链接"""
# 访问城区的页面
self.driver.get(item['partURL'])
# 切换到'最新发布'页面
self.driver.find_element(By.LINK_TEXT, '最新发布').click()
# 获取到所有的房子链接
house_ls = self.driver.find_elements(By.XPATH, '//ul[@class="sellListContent"]//div[@class="title"]/a')
# 生成url列表
house_url_ls = [house.get_attribute("href") for house in house_ls]
# 遍历房子的链接
for url in house_url_ls:
item['houseURL'] = url
self.house_detail(item)
def run(self, city,folder_path):
"""获取所有城区的页面链接"""
# 访问二手房网址
self.driver.get(f'https://{city}.lianjia.com/ershoufang/')
# 获取所有城区的元素对象
temp_ls = self.driver.find_elements(By.XPATH, '//div[@class="position"]/dl[2]/dd/div[1]/div/a')
# 城区名
part_name_ls = [ele.text for ele in temp_ls]
# 城区链接
part_url_ls = [ele.get_attribute("href") for ele in temp_ls]
item = {} # 初始化一个容器, 用来存放房子的信息
for i in range(len(temp_ls)):
item['partName'] = part_name_ls[i] # 城区名
item['partURL'] = part_url_ls[i] # 城区页面链接
self.house_list(dict(item)) # 传递深拷贝的item对象
pd.DataFrame(item).to_csv(folder_path+f'\{city}.csv', index=False, encoding='utf-8')
self.driver.quit()
for city in cities:
# 创建目录
folder_path = os.getcwd()+f"\data\房价\{city}"
if not os.path.exists(folder_path):
os.makedirs(folder_path)
city1 = pinyin.get_initial(city).replace(" ", "")
lj = LianJia()
lj.run(city1,folder_path)