近年来随着我国二手房市场的逐渐放开,进入市场的二手房数量不断增长,二手房交易规模不断扩大,市场规模也在不断增加。数据显示,截至2018年底,我国累计二手房交易金额已经超过30万亿元;2019年我国二手房市场规模6.7万亿元,预计到2021年将达到8.4万亿元。
众所周知,发展二手房市场对于稳定住房价格,引导梯次消费,实现住房市场的健康发展具备重要的现实意义。但不能否认,二手房市场有效房源依旧供不该求,总体供求比例仅维持在1:4左右。现在,因为城市的扩张,新楼房一般只能建于远离城市中心之地,交通便利性较差,远不如建于城市中心地带的二手房。
对于二手房信息,咱们也要多了解css
输入城市拼音的首字母,以及爬取的页数便可python
20210605_235436web
python
pycharm
tkinter库(python内置库)
parsel库ide
1.打开网址(采用链家网长沙二手房的网址)
https://cs.lianjia.com/ershoufang/pg1/
2.观察url变化,点击第二页,第三页
https://cs.lianjia.com/ershoufang/pg2/
https://cs.lianjia.com/ershoufang/pg3/
3.观察网址是什么加载方式
能够肯定为同步加载svg
4.打开北京链家二手房信息,记录url地址,观察url地址的变化
https://bj.lianjia.com/ershoufang/
能够看出bj为北京首字母
5.开始写爬虫代码
解析获取文本内容 一、导包 二、变成CSS选择器对象
因为获取的内容都在ul标签下的li标签
变成CSS选择器对象,下图详解
函数
for page in range(1, pass_wd+1): start_url = f'https://{ user_name}.lianjia.com/ershoufang/pg{ page}/' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 ' '(KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36' } response = requests.get(start_url, headers=headers).content.decode() # pprint(response) selector = parsel.Selector(response) # 解析获取文本内容 一、导包 二、变成CSS选择器对象 lis = selector.css('.sellListContent li') # self.text1.insert('insert', lis) dit = { } for li in lis: title = li.css('.title a::text').get() dit['标题'] = title positionInfo = li.css('.positionInfo a::text').getall() info = '-'.join(positionInfo) dit['开发商'] = info houseInfo = li.css('.houseInfo::text').get() dit['房子信息'] = houseInfo followInfo = li.css('.followInfo::text').get() dit['发布周期'] = followInfo Price = li.css('.totalPrice span::text').get() dit['售价/万'] = Price unitPrice = li.css('.unitPrice span::text').get() dit['单价'] = unitPrice
def __init__(self): """定义可视化窗口,并设置窗口和主题大小布局""" self.window = tk.Tk() self.window.title('城市二手房数据采集') self.window.geometry('800x600') """建立label_user按钮,与说明书""" self.label_user = tk.Label(self.window, text='要爬取的城市首字母:', font=('Arial', 12), width=30, height=2) self.label_user.pack() """建立label_user关联输入""" self.entry_user = tk.Entry(self.window, show=None, font=('Arial', 14)) self.entry_user.pack(after=self.label_user) """建立label_passwd按钮,与说明书""" self.label_passwd = tk.Label(self.window, text="爬取多少页:(小于100)", font=('Arial', 12), width=30, height=2) self.label_passwd.pack() """建立label_passwd关联输入""" self.entry_passwd = tk.Entry(self.window, show=None, font=('Arial', 14)) self.entry_passwd.pack(after=self.label_passwd) """建立Text富文本框,用于按钮操做结果的展现""" self.text1 = tk.Text(self.window, font=('Arial', 12), width=85, height=22) self.text1.pack() """定义按钮1,绑定触发事件方法""" self.button_1 = tk.Button(self.window, text='爬取', font=('Arial', 12), width=10, height=1, command=self.parse_hit_click_1) self.button_1.pack(before=self.text1) """定义按钮2,绑定触发事件方法""" self.button_2 = tk.Button(self.window, text='清除', font=('Arial', 12), width=10, height=1, command=self.parse_hit_click_2) self.button_2.pack(anchor="e")
代码注释很详细,这里不过多介绍,
注意:定义按钮,要绑定触发事件方法,command工具
def center(self): """建立窗口居中函数方法""" ws = self.window.winfo_screenwidth() hs = self.window.winfo_screenheight() x = int((ws / 2) - (800 / 2)) y = int((hs / 2) - (600 / 2)) self.window.geometry('{}x{}+{}+{}'.format(800, 600, x, y))
def parse_hit_click_2(self): """定义触发事件2,删除文本框中内容""" self.entry_user.delete(0, "end") self.entry_passwd.delete(0, "end") self.text1.delete("1.0", "end")
import tkinter as tk import requests, parsel from pprint import pprint class TKSpider(object): def __init__(self): """定义可视化窗口,并设置窗口和主题大小布局""" self.window = tk.Tk() self.window.title('城市二手房数据采集') self.window.geometry('800x600') """建立label_user按钮,与说明书""" self.label_user = tk.Label(self.window, text='要爬取的城市首字母:', font=('Arial', 12), width=30, height=2) self.label_user.pack() """建立label_user关联输入""" self.entry_user = tk.Entry(self.window, show=None, font=('Arial', 14)) self.entry_user.pack(after=self.label_user) """建立label_passwd按钮,与说明书""" self.label_passwd = tk.Label(self.window, text="爬取多少页:(小于100)", font=('Arial', 12), width=30, height=2) self.label_passwd.pack() """建立label_passwd关联输入""" self.entry_passwd = tk.Entry(self.window, show=None, font=('Arial', 14)) self.entry_passwd.pack(after=self.label_passwd) """建立Text富文本框,用于按钮操做结果的展现""" self.text1 = tk.Text(self.window, font=('Arial', 12), width=85, height=22) self.text1.pack() """定义按钮1,绑定触发事件方法""" """即登陆按钮,当点击时将执行parse_hit_click_1方法。在真实使用场景中""" """parse_hit_click_1中可替换为本身写的真正登陆函数。这里仅为示例""" self.button_1 = tk.Button(self.window, text='爬取', font=('Arial', 12), width=10, height=1, command=self.parse_hit_click_1) self.button_1.pack(before=self.text1) """定义按钮2,绑定触发事件方法""" self.button_2 = tk.Button(self.window, text='清除', font=('Arial', 12), width=10, height=1, command=self.parse_hit_click_2) self.button_2.pack(anchor="e") def parse_hit_click_1(self): """定义触发事件1,调用main函数""" user_name = self.entry_user.get() pass_wd = int(self.entry_passwd.get()) self.main(user_name, pass_wd) def main(self, user_name, pass_wd): """爬虫函数""" # 抓取每页的url for page in range(1, pass_wd+1): start_url = f'https://{ user_name}.lianjia.com/ershoufang/pg{ page}/' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 ' '(KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36' } response = requests.get(start_url, headers=headers).content.decode() # pprint(response) selector = parsel.Selector(response) # 解析获取文本内容 一、导包 二、变成CSS选择器对象 lis = selector.css('.sellListContent li') # self.text1.insert('insert', lis) dit = { } for li in lis: title = li.css('.title a::text').get() dit['标题'] = title positionInfo = li.css('.positionInfo a::text').getall() info = '-'.join(positionInfo) dit['开发商'] = info houseInfo = li.css('.houseInfo::text').get() dit['房子信息'] = houseInfo followInfo = li.css('.followInfo::text').get() dit['发布周期'] = followInfo Price = li.css('.totalPrice span::text').get() dit['售价/万'] = Price unitPrice = li.css('.unitPrice span::text').get() dit['单价'] = unitPrice """爬取的内容展现在文本框中""" self.text1.insert("insert", dit) self.text1.insert("insert", '\n ') # 添加换行,好观察一点 self.text1.insert("insert", '\n ') printinfo = print(f'*********第{ page}页打印完成*********') def parse_hit_click_2(self): """定义触发事件2,删除文本框中内容""" self.entry_user.delete(0, "end") self.entry_passwd.delete(0, "end") self.text1.delete("1.0", "end") def center(self): """建立窗口居中函数方法""" ws = self.window.winfo_screenwidth() hs = self.window.winfo_screenheight() x = int((ws / 2) - (800 / 2)) y = int((hs / 2) - (600 / 2)) self.window.geometry('{}x{}+{}+{}'.format(800, 600, x, y)) def run_loop(self): """禁止修改窗体大小规格""" self.window.resizable(False, False) """窗口居中""" self.center() """窗口维持--持久化""" self.window.mainloop() if __name__ == '__main__': t = TKSpider() t.run_loop()
代码写完以后打包一下
命令行输入pyinstaller -F 文件.py
打包好后oop
此处代码还不够完善,但愿各位可以一块儿讨论,指点迷津。。
原创不易,但愿各位可以一键三连,小弟在此谢谢了。
快去点赞收藏吧各位布局