Xpath插件的安装
链接:https://pan.baidu.com/s/1T3V11Ev8dPODa2fCRbeuCg
提取码:qvzf
将这个安装包解压缩
打开谷歌浏览器的扩展程序 ----> 打开开发者模式 ----> 点击加载已解压的扩展程序 ----> 选择解压的文件夹
看下图操作
就会出现这个
浏览器导航栏上也会出现X图标
点击图标就会弹出 再点击就会关闭(或者使用快捷键ctrl+shift+X) 会出现这样的黑框 左边写Xpath语法 右面是匹配到的结果 还可以看到匹配到的数量
需要自己去学习一下Xpath定位的语法 很简单的 这里就不赘述了
爬取重庆花溪附近的房源信息(进入正题啦~)
先看一下页面的样子,梳理下逻辑
列表页页面
列表页的分页按钮
详情页页面(点击列表页标题进入)
梳理下逻辑
我们先根据分页获得某一页的列表页,然后爬取列表页的房价,然后进入详情页,爬取详情页的下列信息
爬取数据的通用流程
根据url请求页面,获取页面响应对象(也就是下面代码中的html_obj = requests.get(url=url, headers=headers))
将页面响应对象转化为etree/parsel对象 (tree = etree.HTML(html_obj))
定位要爬取的数据 (tree.xpath(’…’))
获取数据
持久化存储
代码
终于到了心心念念,激动人心的时刻啦~~ 上代码!!!哈哈哈
写了注释了,不过多解释
from collections import defaultdict
import requests
import pandas as pd
from lxml import etree
import re
# 获取到分页url的一个统一格式
url_all = 'https://chongqing.anjuke.com/sale/p{}-rd1/?kw=%E8%8A%B1%E6%BA%AA#filtersort'
# 请求头
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
}
def get_url_list(url): '''获取url列表 用于分页获取内容''' url_list = [url.format(i) for i in range(1, 21)] # 获取20页 return url_list
def get_page_etree(url, headers): '''得到页面的etree对象''' html_obj = requests.get(url=url, headers=headers)# 根据url请求页面,获取页面响应对象html_obj html_obj = html_obj.content.decode() # 解决乱码问题 tree = etree.HTML(html_obj) # 转化为页面的etree对象 return tree
def get_data(tree): """获取一页的房子数据""" # 建立字典 info_dicts = defaultdict(list) # 定位到一页列表页的所有li标签 li_list = tree.xpath('//ul[@id="houselist-mod-new"]/li') for li in li_list: # 遍历每一条(li标签) 一个li就对应着一个房子 一个房子的数据全部爬取完再爬取下一个房子,一页爬取完再爬下一页 # 列表页 获取价格 jiage = li.xpath('./div[@class="pro-price"]//strong/text()')[0] info_dicts['价格(万)'].append(jiage) # 接下来进入详情页 获取其他数据 # 先获取a链接href属性值 再跳转到该链接进行爬取 a = li.xpath('.//div[@class="house-title"]/a/@href')[0] # 获取详情页etree对象 tree_i = get_page_etree(url=a, headers=headers) # 解析数据 hx = tree_i.xpath('//ul[@class="houseInfo-detail-list clearfix"]/li[2]/div[2]/text()')[0].strip().split() info_dicts['户型-房间'].append(hx[0]) info_dicts['户型-厅'].append(hx[1]) info_dicts['户型-卫生'].append(hx[2]) # 建筑面积 mj = tree_i.xpath('//ul[@class="houseInfo-detail-list clearfix"]/li[5]/div[2]/text()')[0] info_dicts['建筑面积'].append(mj) # 朝向 cx = tree_i.xpath('//ul[@class="houseInfo-detail-list clearfix"]/li[8]/div[2]/text()')[0] info_dicts['朝向'].append(cx) # 小区 xq = tree_i.xpath('//ul[@class="houseInfo-detail-list clearfix"]/li[1]/div[2]/a/text()')[0].strip() info_dicts['小区'].append(xq) # 地址 dz = tree_i.xpath('//ul[@class="houseInfo-detail-list clearfix"]/li[4]/div[2]/p/text()')[1].strip().split()[1] info_dicts['地址'].append(dz) # 建筑时间 jzsj = tree_i.xpath('//ul[@class="houseInfo-detail-list clearfix"]/li[7]/div[2]/text()')[0].strip() info_dicts['建筑时间'].append(jzsj) # 总楼层 所处层数 str = tree_i.xpath('//ul[@class="houseInfo-detail-list clearfix"]/li[11]/div[2]/text()')[0] zlc = re.search(r'\d+', str, re.A).group() # 这里用到了正则表达式提取信息 info_dicts['总楼层'].append(zlc) cs = re.search(r"['高','中','低']", str, re.U) if cs is None: cs = '' else: cs = cs.group() info_dicts['所处层数'].append(cs) # 装修 zx = tree_i.xpath('//ul[@class="houseInfo-detail-list clearfix"]/li[12]/div[2]/text()')[0] info_dicts['装修'].append(zx) # 电梯 dt = tree_i.xpath('//ul[@class="houseInfo-detail-list clearfix"]/li[14]/div[2]/text()')[0] info_dicts['电梯'].append(dt) data = pd.DataFrame(info_dicts) return data
# 主程序部分
data = pd.DataFrame()
# 获取url列表 用于分页爬取
url_list = get_url_list(url_all)
for i, url in enumerate(url_list): # 获取每一页的列表页etree对象 tree = get_page_etree(url=url,headers=headers) # 得到所有数据追加到data中 data = data.append(get_data(tree),ignore_index=True) print('第',i+1,'页爬取成功!')
# 持久化存储
data.to_excel('重庆花溪房源数据.xls')1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
请求头
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
}1
2
3
这里从这里找,复制 粘贴它
代码的问题 & 运行时可能出现的问题
存数据是爬到所有数据一次从DataFrame存到excel里,如果数据太大可能内存会吃不消,可以自己尝试下一页一追加到excel里,我这个20页(页数可以改的哈)1200条数据也还可以,数据量不大
如果报错就从网页手动访问页面,看是不是被人家的系统检测到你爬取了,就像下面这样 就换个网 刷新下页面能访问到列表页 再运行程序爬取
或者可能会出现验证码,手动通过验证码 ,刷新页面,再爬取就ok
建议多刷新下页面试试,能手动的访问到列表页一般就能正常爬下数据来
结果
(电梯那一栏 有“满三年”值 是因为 不是所有房子的详情页的是否有电梯那个数据都在同一位置上,他那个格式不是很统一,就会爬错)
爬虫学习视频推荐,我从B站这个视频学了学,觉得不错附上链接
https://www.bilibili.com/video/BV1Yh411o7Sz?t=825&p=25
xpath语法讲挺好的视频:https://www.bilibili.com/video/BV14K411L7T5 (就是打广告有点多~~)
加油,你是最胖的,欧耶~~
转载请附上我的链接哦~
欢迎点赞+转发+评论+讨论~~
感谢支持~
数据处理部分(写给我自己哒~)
import pandas as pd
data = pd.read_excel(r'C:/Users/user/Desktop/housePrice.xls')
# 处理缺失值
data = data.dropna(axis=0,subset=['所处层数'])
# 处理 电梯 异常值
data = data[data['电梯']!='满三年']
# 字符型改成数值型数据
# 小区
xq = data['小区'].unique()
xq_dict = {value:key for key, value in enumerate(xq)}
print(xq_dict)
data['小区'] = [xq_dict[i] for i in data['小区']]
# 朝向
cx = data['朝向'].unique()
cx_dict = {value:key for key, value in enumerate(cx)}
print(cx_dict)
data['朝向'] = [cx_dict[i] for i in data['朝向']]
# 地址
dz = data['地址'].unique()
dz_dict = {value:key for key, value in enumerate(dz)}
print(dz_dict)
data['地址'] = [dz_dict[i] for i in data['地址']]
# 所处层数
cs = data['所处层数'].unique()
cs_dict = {value:key for key, value in enumerate(cs)}
print(cs_dict)
data['所处层数'] = [cs_dict[i] for i in data['所处层数']]
# 装修
zx = data['装修'].unique()
zx_dict = {value:key for key, value in enumerate(zx)}
print(zx_dict)
data['装修'] = [zx_dict[i] for i in data['装修']]
# 电梯
dt = data['电梯'].unique()
dt_dict = {value:key for key, value in enumerate(dt)}
print(dt_dict)
data['电梯'] = [dt_dict[i] for i in data['电梯']]
data.to_excel('housePrice.xlsx')
# print(data)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
{‘溪山玥’: 0, ‘申烨太阳城’: 1, ‘日月山庄’: 2, ‘宗申动力城’: 3, ‘碧桂园渝南首府’: 4, ‘宗申青年国际’: 5, ‘浣溪锦云’: 6, ‘华润澜山望’: 7, ‘东原桐麓’: 8, ‘芸峰兰亭’: 9, ‘东海定南山’: 10, ‘曦圆丽景’: 11, ‘保利林语溪’: 12, ‘蔚蓝时光’: 13}
{‘南’: 0, ‘南北’: 1, ‘东南’: 2, ‘北’: 3, ‘东’: 4, ‘西南’: 5, ‘东北’: 6, ‘西北’: 7, ‘西’: 8}
{‘渝南分流道’: 0, ‘渝南大道158号附45号’: 1, ‘渝南大道118号’: 2, ‘渝南大道130号’: 3, ‘渝南大道91号’: 4, ‘渝南大道158号’: 5, ‘渝南大道129号’: 6, ‘龙鸣路’: 7, ‘渝南大道123号’: 8, ‘龙洲大道1958号’: 9, ‘渝南大道115号’: 10, ‘青龙湾路’: 11, ‘渝南大道9号’: 12, ‘渝南大道8号’: 13}
{‘中’: 0, ‘低’: 1, ‘高’: 2}
{‘毛坯’: 0, ‘精装修’: 1, ‘简单装修’: 2, ‘豪华装修’: 3}
{‘有’: 0, ‘无’: 1}
文章来源: blog.csdn.net,作者:静静_jingjing,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/qq_39321513/article/details/111656257