如何使用Scrapy高效爬取房地产网站 现有代码运行无结果求助
问题排查与修复方案
一、现有代码核心错误
- 未提取详情页链接:代码中
Request(link, ...)里的link变量未定义,没有从列表页房源卡片中提取详情页的href属性 - 缺失详情页解析方法:
parse_details回调方法完全未实现,无法处理详情页返回的内容 - 自定义请求未携带请求头:已经定义的
headers参数没有传递给Request,容易被网站反爬策略拦截 - 入口URL不全:
start_urls仅配置了2个分页,未覆盖要求的1-5分页和基础URL - 字段提取逻辑有崩溃风险:
date字段直接调用extract_first().strip(),如果提取结果为None会直接抛出异常终止爬虫 - 未处理相对路径:提取到的详情页链接是相对路径,没有转成可直接请求的绝对路径
二、修正后可运行代码
# -*- coding: utf-8 -*- import scrapy from scrapy.crawler import CrawlerProcess from scrapy import Request class UneguiApartments(scrapy.Spider): name = 'unegui_apts' allowed_domains = ['www.unegui.mn'] # 配置爬取参数、导出规则 custom_settings = { 'FEEDS': { 'results1.csv': { 'format': 'csv', 'encoding': 'utf-8-sig', # 保证西里尔字符正常显示,Excel打开也不会乱码 'overwrite': True # 每次运行覆盖旧文件,可按需修改 } }, 'CONCURRENT_REQUESTS': 32, # 并发请求数,默认16,合理提升可加快爬取速度 'DOWNLOAD_DELAY': 0.25, # 下载间隔,避免请求过频被封 'DUPEFILTER_CLASS': 'scrapy.dupefilters.RFPDupeFilter', # 自动去重,保证房源唯一 'RETRY_TIMES': 3 # 请求失败重试次数 } # 生成所有入口URL:基础页+1-5分页 start_urls = ['https://www.unegui.mn/l-hdlh/l-hdlh-zarna/oron-suuts-zarna/'] + [f'https://www.unegui.mn/l-hdlh/l-hdlh-zarna/oron-suuts-zarna/{i}-r/' for i in range(1,6)] headers = { 'user-agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" } def parse(self, response): cards = response.xpath('//div[@class="list-announcement-block"]') for card in cards: # 提取列表页字段,增加判空避免崩溃 name = card.xpath('.//meta[@itemprop="name"]/@content').extract_first() price = card.xpath('.//meta[@itemprop="price"]/@content').extract_first() city = card.xpath('.//meta[@itemprop="areaServed"]/@content').extract_first() date_raw = card.xpath('.//*[@class="announcement-block__date"]/text()').extract_first() date = date_raw.strip().split(', ')[0] if date_raw else None # 提取详情页相对路径,转成绝对路径 link = card.xpath('.//a[@class="announcement-block__title"]/@href').extract_first() if not link: continue detail_url = response.urljoin(link) # 携带参数请求详情页 yield Request( url=detail_url, headers=self.headers, callback=self.parse_details, meta={'name': name, 'price': price, 'city': city, 'date': date, 'detail_url': detail_url} ) # 自动翻页 next_url = response.xpath('//li[@class="pager-next"]/a/@href').get() if next_url: yield response.follow(next_url, callback=self.parse, headers=self.headers) def parse_details(self, response): # 接收列表页传递的参数 item = response.meta # 提取详情页span标签内容,可按需修改xpath匹配你需要的字段 # 示例:提取面积、户型、楼层等字段 item['area'] = response.xpath('//span[contains(text(),"м²")]/text()').extract_first() item['room_count'] = response.xpath('//span[contains(text(),"өрөө")]/text()').extract_first() # 可继续添加其他需要提取的span字段 yield item if __name__ == "__main__": process = CrawlerProcess() process.crawl(UneguiApartments) process.start()
三、使用说明
- 直接运行py文件或者执行
scrapy crawl unegui_apts命令都可启动爬虫 - 导出的CSV文件默认保存在运行目录下,
utf-8-sig编码可完整保留西里尔字符,兼容各类办公软件 - 爬取速度可通过调整
CONCURRENT_REQUESTS和DOWNLOAD_DELAY参数平衡,若出现被封情况可降低并发、增加延迟 - 不需要额外配置数据管道,内置的FEEDS配置已经可以满足CSV导出需求,Scrapy默认异步架构比BeautifulSoup单线程爬取效率高5-10倍,可在数分钟内完成5000-7000条数据采集
内容的提问来源于stack exchange,提问作者WX1505
相关产品推荐
相关产品推荐

