青客公寓分城市爬取

  • 背景
  • 思路
  • 完整代码
  • 代码解读
  • 后思考
  • 免责申明

背景

搬家了,从原来的二房东搬到现在的二房东,只不过以前是个人二房东,现在是青客二房东管家,上班距离也从原来的10分钟增加到40分钟,时间成本的增加带来的是居住舒适度和居住环境的改善,对面青客这样一家专门做分散式集中公寓运营的企业,在交了两个月押金后还要做“租金贷”的冒险才能优惠一点,真想好好评估一下青客市场实力,预防其跑路,要研究别人,首先你得有别人的数据才行,故先简单爬取她家在各个城市挂牌房源瞅瞅。

思路

从其官网获取每套挂牌房源信息,并把相应的信息写入mysql,每个房源包含的字段有房源名称,房源编码,价格,朝向,楼层,小区名称,板块,区域,原详情页网址,地址等,由于其网页是分城市的挂牌房源信息,所以在程序设计的时候留两个入口,一个是城市简称,一个这个城市总网页数,先构造一级网页,然后通过一级网页获取每个房源的详情页,最后通过进入详情页获取想要的字段并组合成一条数据存入数据库mysql。

完整代码

# -*- coding: utf-8 -*-
"""
Created on Fri Jul 26 09:31:55 2019
title:qingke365
@author: 帅帅de三叔
"""
import requests #导入请求模块
import time #导入时间功能模块
from tqdm import tqdm #导入进度条模块
from bs4 import BeautifulSoup #导入网页解析模块
import re #导入正则表达模块
header={"User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"} #请求头print("connecting mysql……\n")
import pymysql #导入pymysql模块
db=pymysql.connect("localhost","root","123456","qingke",charset='utf8') #链接mysql数据库community
print("connect successfully,start creating table qingke_sh in database qingke\n")
cursor=db.cursor() #创建游标对象
cursor.execute("DROP TABLE IF EXISTS qingke_sh") #如果community_sh存在则drop掉
c_sql="""CREATE TABLE qingke_sh(district varchar(10),plate varchar(12),  title varchar(50),code varchar(12),price varchar(6),toward varchar(6),floor varchar(6),community varchar(8)    )ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8"""
cursor.execute(c_sql) #创建一个表ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
print("table qingke_sh has been created\n")def generate_page(city,num):#定义获取所有网页函数url="https://"+city+".qk365.com/list/p{}" #初始网址for url_next in range(1,int(num)+1):yield url.format(url_next) def get_detail_url(generate_page): #定义获取每一个房源详情页的链接入口response=requests.get(generate_page,headers=header) #发出一级请求#time.sleep(1) #进程挂起的时间soup=BeautifulSoup(response.text,'lxml') #解析网页contents=soup.find("ul",class_="easyList").find_all("li") #所有在售房源列表if contents: for content in contents:#print(content)detail_url=content.find("a")['href'] #详情页网址print(detail_url)res=requests.get(detail_url,headers=header) #根据详情页二级请求网time.sleep(1) #进程挂起的时间soup=BeautifulSoup(res.text,'lxml') #解析详情页网页title=soup.find("div",class_="HouInfoL").find("h1",class_="houInfoTit").get_text().replace(" ","").strip() #去掉空格,并去掉前后空格code_pattern=re.compile("[a-zA-Z0-9]+") #用以正则房间编号code=re.search(code_pattern,soup.find("div",class_="survey-right fR").find("dd").get_text()).group(0) #房间编号pattern_price=re.compile("\d+") #用以正则价格price=re.search(pattern_price,soup.find("div",class_="survey-left fL").find("dd").get_text()).group(0) #价格toward=soup.find("div",class_="survey-left fL").findAll("dd")[2].find("em").get_text() #朝向floor=soup.find("div",class_="survey-left fL").findAll("dd")[3].get_text().replace(" ","").split(':')[-1] #楼层community=soup.find("div",class_="survey-left fL").findAll("dd")[4].find("a").get_text() #小区名称district=soup.find("div",class_="survey-right fR").findAll("dd")[3].find("a").get_text() #区域plate_content=soup.find("div",class_="survey-right fR").findAll("dd")[3] #板块plate=plate_content.findAll("a")[-1].get_text() #板块print(district,plate,title,code,price,toward,floor,community)insert_data=("INSERT INTO qingke_sh(district,plate,title,code,price,toward,floor,community)""VALUES(%s,%s,%s,%s,%s,%s,%s,%s)") #控制插入数据格式qingke_data=([district,plate,title,code,price,toward,floor,community]) #组成一条记录cursor.execute(insert_data,qingke_data) #执行插入操作db.commit() #主动提交def main():#定义主函数city=input("please input the abbreviate name of city:") #输入城市简称num=input("please input total page num:") #输入总页数for page_link in tqdm(generate_page(city,num)):get_detail_url(page_link)if __name__=="__main__":main()

代码解读

代码只需要输入每个城市的简称和总网页数,比如要获取上海的则输入sh,总页数254,然后根据generate_page函数构造出所有一级网页,紧接着用get_detail_url函数去获取每个房源的详情页,这里用generate_page作为其输入参数,然后利用get_detail_url函数进入详情页获取想要的字段并存入数据库,程序去获取青客在上海的每个房源的具体信息形成字段结构化数据存入mysql里面去,最后定义一个主函数main()把前面的几个函数功能整合起来。

后思考

首先,爬虫要考虑对方服务器的承受力,暴力爬虫不可取,可以通过time.sleep()挂起那么一小段时间;其次,要考虑程序的泛化能力,即今天可以用来爬青客,下次可以稍微修改一下可以用来爬其他类似的网站;这种程序设计有其好的一面就是分城市爬取,每次需要输入城市简称和总网页数,一个城市需要执行一次程序,一是一,二是二;也有不好的一面,比如每次都要去网页查找最后一页数字,属于半自动化,下一次可以尝试通过判断条件来定位当前爬取的是否是最后一页,而不再需要手动输入总页码数,同时对于这种大量读写操作,程序执行略慢,可以考虑多线程和多进程或者异步处理。下面利用asyncio模块进行异步爬取。修改代码如下

# -*- coding: utf-8 -*-
"""
Created on Fri Jul 26 09:31:55 2019
title:qingke365
@author: Uncle Three
"""
import requests #导入请求模块
import time #导入时间功能模块
import asyncio #导入异步IO模块
from bs4 import BeautifulSoup #导入网页解析模块
import re #导入正则表达模块
header={"User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"} #请求头
start_time=time.time() #起始时间
print("connecting mysql……\n")
import pymysql #导入pymysql模块
db=pymysql.connect("localhost","root","123456","qingke",charset='utf8') #链接mysql数据库community
print("connect successfully,start creating table qingke_wh in database qingke\n")
cursor=db.cursor() #创建游标对象
cursor.execute("DROP TABLE IF EXISTS qingke_wh") #如果community_sh存在则drop掉
c_sql="""CREATE TABLE qingke_wh(district varchar(10),plate varchar(12),  title varchar(50),code varchar(12),price varchar(6),toward varchar(6),floor varchar(6),community varchar(8),detail_url varchar(35))ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8"""
cursor.execute(c_sql) #创建一个表ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
print("table qingke_wh has been created\n")def generate_page(city,num):#定义获取所有网页函数url="https://"+city+".qk365.com/list/p{}" #初始网址for url_next in range(1,int(num)+1):yield url.format(url_next) async def get_detail_item(generate_page): #定义获取每一个房源详情页的链接入口获取字段的异步函数response=requests.get(generate_page,headers=header) #发出一级请求soup=BeautifulSoup(response.text,'lxml') #解析网页contents=soup.find("ul",class_="easyList").find_all("li") #所有在售房源列表if contents: for content in contents:#print(content)detail_url=content.find("a")['href'] #详情页网址#print(detail_url)res=requests.get(detail_url,headers=header) #根据详情页二级请求网time.sleep(1) #进程挂起的时间soup=BeautifulSoup(res.text,'lxml') #解析详情页网页title=soup.find("div",class_="HouInfoL").find("h1",class_="houInfoTit").get_text().replace(" ","").strip() #去掉空格,并去掉前后空格code_pattern=re.compile("[a-zA-Z0-9]+") #用以正则房间编号code=re.search(code_pattern,soup.find("div",class_="survey-right fR").find("dd").get_text()).group(0) #房间编号pattern_price=re.compile("\d+") #用以正则价格price=re.search(pattern_price,soup.find("div",class_="survey-left fL").find("dd").get_text()).group(0) #价格toward=soup.find("div",class_="survey-left fL").findAll("dd")[2].find("em").get_text() #朝向floor=soup.find("div",class_="survey-left fL").findAll("dd")[3].get_text().replace(" ","").split(':')[-1] #楼层community=soup.find("div",class_="survey-left fL").findAll("dd")[4].find("a").get_text() #小区名称district=soup.find("div",class_="survey-right fR").findAll("dd")[3].find("a").get_text() #区域plate_content=soup.find("div",class_="survey-right fR").findAll("dd")[3] #板块内容plate=plate_content.findAll("a")[-1].get_text() #板块print(district,plate,title,code,price,toward,floor,community,detail_url)insert_data=("INSERT INTO qingke_wh(district,plate,title,code,price,toward,floor,community,detail_url)""VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s)") #控制插入数据格式qingke_data=([district,plate,title,code,price,toward,floor,community,detail_url]) #组成一条记录cursor.execute(insert_data,qingke_data) #执行插入操作db.commit() #主动提交def main():#定义主函数city=input("please input the abbreviate name of city:") #输入城市简称num=input("please input total page num:") #输入总页数loop=asyncio.get_event_loop() #创建一个异步循环tasks=[asyncio.ensure_future(get_detail_item(page_link)) for page_link in generate_page(city,num)] #通过 `ensure_future` 函数计划执行创建一个任务盒子tasks,每个任务为一页page的工作量#tasks = asyncio.gather(*tasks) #把多个协程任务交给 looploop.run_until_complete(asyncio.wait(tasks)) #tasks接入loop中开始运行loop.close()
if __name__=="__main__":main()
end_time=time.time() #结束时间
print("run time:",end_time-start_time)

在写入mysql的时候如果报错及解决办法

  DataError: (1406, "Data too long for column 'community' at row 1")

在mysql命令里面执行下面语句

SET @@global.sql_mode= '';
  Warning: (1265, "Data truncated for column 'code' at row 1")

在mysql命令里面执行下面语句或者创建表的时候varchar()括号里面数字调大一些

code varchar(12) 变成code varchar(15)

免责申明

Python爬虫仅为学习交流,如有冒犯,请告知删。

青客公寓挂牌房源分城市爬取相关推荐

  1. 建方公寓挂牌房源信息爬取

    爬取建方公寓挂牌房源信息 背景 完整代码 后话 背景 自从青客公寓分城市挂牌房源和优客逸家挂牌房源爬取之后,发现爬虫也挺有趣的,于是今天又拿建方公寓练手,差点栽跟头了,且听我慢慢道来.有前两次爬虫经验 ...

  2. 背上“租金贷”包袱,青客公寓还能“跑”吗?

    2019年,互联网长租公寓行业马太效应加剧,行业聚集度将进一步提升.资金流进了企业头部玩家,头部企业掀起了上市热潮,蛋壳.自如先后被爆出谋求上市消息. 然而"长租第一股"最终花落青 ...

  3. 外媒称青客公寓计划赴美IPO 筹资1.5亿美元

    [TechWeb]10月3日,中国公寓租赁服务提供商青客正在计划美国IPO,筹资约1亿至1.5亿美元.青客可能最快本月向美国证券交易委员会(SEC)提交IPO文件. 资料显示,青客于2012年成立于上 ...

  4. 博客搬家系列(六)-爬取今日头条文章

    博客搬家系列(六)-爬取今日头条文章 一.前情回顾 博客搬家系列(一)-简介:https://blog.csdn.net/rico_zhou/article/details/83619152 博客搬家 ...

  5. python爬取房源数据_python爬取安居客二手房网站数据(实例讲解)

    是小打小闹 哈哈,现在开始正式进行爬虫书写首先,需要分析一下要爬取的网站的结构:作为一名河南的学生,那就看看郑州的二手房信息吧! 在上面这个页面中,我们可以看到一条条的房源信息,从中我们发现了什么,发 ...

  6. php爬取房源,Python 爬虫 链家二手房(自行输入城市爬取)

    因同事想在沈阳买房,对比分析沈阳各区的房价,让我帮忙爬取一下链家网相关数据,然后打 算记下笔记 用于总结学到的东西&用到的东西. 一.爬虫需要会什么? 学习东西 首先你要知道它是干嘛的.爬虫 ...

  7. python爬虫爬取房源_python爬虫爬取安居客房源信息

    Xpath插件的安装 链接:https://pan.baidu.com/s/1T3V11Ev8dPODa2fCRbeuCg 提取码:qvzf 将这个安装包解压缩 打开谷歌浏览器的扩展程序 ----&g ...

  8. python爬虫requests源码链家_Python 爬虫 链家二手房(自行输入城市爬取)

    因同事想在沈阳买房,对比分析沈阳各区的房价,让我帮忙爬取一下链家网相关数据,然后打 算记下笔记 用于总结学到的东西&用到的东西. 一.爬虫需要会什么? 学习东西 首先你要知道它是干嘛的.爬虫 ...

  9. php爬取房源,用python爬取二手房交易信息并进行分析

    用python爬取二手房交易信息并分析第一步:编写爬虫 爬取某平台上海市十个区共900条二手房的交易信息#爬取上海十个区的二手房价信息 import requests from bs4 import ...

  10. BIG+碧家国际社区集中式公寓项目爬取

    BIG+碧家国际社区集中式公寓项目爬取 背景 代码 代码解读 结果截图 免责声明 背景 研究组对于集中式公寓项目的数据需求源源不断,这不又需要BIG+碧家国际社区集中式公寓项目在全国各城市的项目名称, ...

最新文章

  1. flexcan controller register
  2. 克隆真人语音只要1句话,AI问诊超96.4%全科医生!科大讯飞年度黑科技大秀,余承东都来了...
  3. 网站快照更新不及时有什么好的解决办法吗?
  4. Discuz!NT 在线用户功能简介
  5. (DFS)求出n个数中选择m个数的所有可能
  6. 肖仰华 | 知识图谱与认知智能
  7. Apache重定向方法实现图片防盗链
  8. PyTorch 1.0 中文文档:多进程包 - torch.multiprocessing
  9. [贪心算法] 例6.1 FatMouse' Trade
  10. 风控中英文术语手册(银行_消费金融信贷业务)
  11. 【 Codeforces Round #395 (Div. 2) E】Timofey and remoduling【数学思维题 —— 等差/等比数列】
  12. redis 可视化客户端工具
  13. 程序员应该阅读的非编程类书籍有哪些?
  14. cmmi证书查询(cmmi认证查询网站)
  15. 哈工大同义词词林 python 使用范例
  16. java excel 字体_java中Excel字体的设置,背景和纹理的操作
  17. provisional headers are shown问题解决
  18. matlab中nnt,Matlab语言的Neural Network Toolbox 及其在同步中
  19. 央行降息后六大城市房价有望反弹(名单)
  20. 【国信安实训】——文件上传漏洞

热门文章

  1. stylecloud 自定义蒙版
  2. 自定义validation注解:解决动态多字段联动校验问题
  3. 16进制是否能整除 求余的运算
  4. Virginie Ruiz
  5. ES6 模板字符串用法
  6. java 计算年龄_Java 根据出生日期计算年龄
  7. HDU6834 Yukikaze and Smooth numbers
  8. 九、多线程(高琪java300集+java从入门到精通笔记)
  9. python壁纸4k_壁纸软件下载|2k4k桌面壁纸自动更换 Python版1.0 下载_当游网
  10. 三角形的分类c语言,C语言 输入三角形的三边,判断三角形的类型,并输出它的类型和面积...