本次是爬取西安房天下上的二手房交易数据,主要面临的困难有:
- 网页的重定向问题的识别
- 不完全规则网页的匹配规则书写问题
- 爬虫效率问题
- 滑块验证问题
import requests
from scrapy.selector import Selector as se
import pandas as pd
import re
headers = {
'Connection': 'keep-alive',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36 Edg/103.0.1264.37',
}
datas = []
fail_url = []
for page in range(73, 76):
# https://xian.esf.fang.com/house/i32/
response = requests.get('https://xian.esf.fang.com/house/i3' str(page 25) '/', headers=headers,
verify=True)
html = response.text
next_page_url = 'https://xian.esf.fang.com/house/i3'
str(page 1) '?' re.findall(r"t3='(.*?)'", html)[0]
response = requests.get(next_page_url, headers=headers,
verify=True)
next_url = se(text=response.text).xpath(
'//h4[@class="clearfix"]/a/@href').extract()
for url in next_url:
response1 = requests.get('https://xian.esf.fang.com' url, headers=headers,
verify=True)
html = response1.text
page_url = 'https://xian.esf.fang.com'
url '?' re.findall(r"t3='(.*?)'", html)[0]
print(f"开始爬取{page_url}")
response = requests.get(page_url, headers=headers,
verify=True)
data = response.text
# print(data)
# //*[@id="lpname"]/h1/span
# title
x1 = se(text=data).xpath(
'//span[@class="tit_text"]/text()').extract_first().replace('n', '').strip()
# 总价
x2 = se(text=data).xpath(
'//div[@class="trl-item price_esf sty1"]/i/text()').extract_first()
# 户型
x3 = se(text=data).xpath(
'//div[text()="户型"]/../div/text()').extract_first()
# '//div[text()="户型"]/../div/text()').extract_first().replace('n', '').strip()
# 建筑面积
x4 = se(text=data).xpath(
'//div[@class="trl-item1 w182"]/div/text()').extract_first()
# 单价
x5 = se(text=data).xpath(
'//div[@class="trl-item1 w132"]/div/text()').extract_first()
# 朝向
x6 = se(text=data).xpath(
'//div[text()="朝向"]/../div[@class="tt"]/text()').extract_first() # .replace('n', '').strip()
# 楼层
x7 = se(text=data).xpath(
'//div[text()="朝向"]/../../div[@class="trl-item1 w182"]/div[@class="tt"]/a/text()').extract_first()
# 总楼层
x27 = se(text=data).xpath(
'//div[text()="朝向"]/../../div[@class="trl-item1 w182"]/div[@class="font14"]/text()').extract_first()
# 装修
x8 = se(text=data).xpath(
'//div[text()="装修"]/../div/a/text()').extract_first()
# 小区
x9 = se(text=data).xpath(
'//div[@class="rcont"]/a/text()').extract_first()
# 小区位置具体描述
x10 = se(text=data).xpath(
'//div[@class="rcont"]/span/text()').extract_first()
# 区
x11 = se(text=data).xpath(
'//div[@id="address"]/a/text()').extract()[0].replace('n', '').strip()
# 区域
x12 = se(text=data).xpath(
'//div[@id="address"]/a/text()').extract()[1].replace('n', '').strip()
# 建筑年代
x13 = se(text=data).xpath(
'//span[text()="建筑年代"]/../span[@class="rcont "]/text()').extract_first()
# 有无电梯
x14 = se(text=data).xpath(
'//span[text()="有无电梯"]/../span[@class="rcont"]/text()').extract_first()
# 产权性质
x15 = se(text=data).xpath(
'//span[text()="产权性质"]/../span[@class="rcont"]/a/text()').extract_first()
# 住宅类别
x16 = se(text=data).xpath(
'//span[text()="住宅类别"]/../span[@class="rcont"]/a/text()').extract_first()
# 建筑结构
x17 = se(text=data).xpath(
'//span[text()="建筑结构"]/../span[@class="rcont"]/a/text()').extract_first()
# 建筑类别
x18 = se(text=data).xpath(
'//span[text()="建筑类别"]/../span[@class="rcont"]/a/text()').extract_first()
# 挂牌时间
if se(text=data).xpath(
'//span[text()="挂牌时间"]/../span[@class="rcont"]/text()').extract_first():
x19 = se(text=data).xpath(
'//span[text()="挂牌时间"]/../span[@class="rcont"]/text()').extract_first().replace('n', '').strip()
else:
x19 = se(text=data).xpath(
'//span[text()="挂牌时间"]/../span[@class="rcont"]/text()').extract_first()
# 参考均价
x20 = se(text=data).xpath(
'//span[text()="参考均价"]/../span/i/text()').extract_first()
# 物业类型
x21 = se(text=data).xpath(
'//span[text()="物业类型"]/../span[@class="rcont "]/text()').extract_first()
# 绿化率
x22 = se(text=data).xpath(
'//span[text()="绿 化 率"]/../span[@class="rcont "]/text()').extract_first()
# 容积率
x23 = se(text=data).xpath(
'//span[text()="容 积 率"]/../span[@class="rcont "]/text()').extract_first()
# 建筑类型
x24 = se(text=data).xpath(
'//span[text()="建筑类型"]/../span[@class="rcont "]/text()').extract_first()
# 人车分流
x25 = se(text=data).xpath(
'//span[text()="人车分流"]/../span[@class="rcont "]/text()').extract_first()
# 总户数
x26 = se(text=data).xpath(
'//span[text()="总 户 数"]/../span[@class="rcont "]/text()').extract_first()
x28 = se(text=data).xpath(
'//span[text()="总楼栋数"]/../span[@class="rcont "]/text()').extract_first()
# 总评分
x29 = se(text=data).xpath(
'//p[text()="房源评级|多维度分析房源"]/../div[@class="num_bg"]/h3/text()').extract_first()
x30 = se(text=data).xpath(
'//p[text()="交易价值"]/../h4/text()').extract_first()
x31 = se(text=data).xpath(
'//p[text()="居住品质"]/../h4/text()').extract_first()
x32 = se(text=data).xpath(
'//p[text()="便利指数"]/../h4/text()').extract_first()
x33 = se(text=data).xpath(
'//p[text()="物业服务"]/../h4/text()').extract_first()
datas.append([x1, x2, x3, x4, x5, x6, x7, x27, x8, x9, x10, x11, x12, x13,
x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x28, x30, x31, x32, x33, x29])
print(f'第{page 1}页数据爬取完成')
final_data = pd.DataFrame(datas, columns=['title', '总价', '户型',
'建筑面积', '单价', '朝向',
'楼层', '总楼层', '装修',
'小区', '小区位置具体描述',
'所属区', '所属具体区域', '建筑年代',
'有无电梯', '产权性质', '住宅类别',
'建筑结构', '建筑类别', '挂牌时间',
'小区参考均价', '物业类型', '绿化率',
'容积率', '小区建筑类型', '人车分流',
'总户数', '总楼栋数', '交易价值',
'居住品质', '便利指数', '物业服务',
'综合评分'])
# final_data=final_data.set_index('id')
final_data.to_excel('数据.xlsx')
上述代码是本次校赛仓促之间写出的代码,还有一些地方需要优化:
本次爬虫总的来看是一次不怎么成功的爬虫项目经历,首先时间限制加上对于Scrapy框架不够熟悉导致在实际爬取数据过程中并没有使用Scrapy框架,临时使用的requests库也存在一些需要优化的地方:
- 没有使用beautifulsoup进行网页文件解析而是用了Scrap框架中的解析库。
- 匹配规则需要进行优化,对房子网页的结构并没有分辨清楚便开始爬虫,用节点文本作为匹配规则导致部分’朝向’位置写成’进门朝向’的数据并没有被匹配到,这直接导致了爬得数据中朝向、楼价、房价一列出现大量缺失,同样的问题也发生在了建筑年代匹配列(属性值分为有空格和没有空格两种)。
- 没有正确分析所需数据需求直接进行盲目爬取,做了很多无用功(这个是老毛病了,遇到问题时冷静思考的能力就丧失了