步骤一:

import requests
from bs4 import BeautifulSoup
import pandas as pd# 获取成都市区(锦江、青羊、武侯、高新、成华、金牛、天府新区、高新西,共8个行政区)租房基本数据信息:
# 要求:每个行政区的租房区域划分情况和挂网租房数量# UA伪装
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ''Chrome/89.0.4389.82 Safari/537.36'
}def getBasicInfomation():"""获取八大城区的名字和网址,并存入列表:return: 返回名字和网址列表"""# 链家成都租房地址url = 'https://cd.lianjia.com/zufang'response = requests.get(url=url, headers=headers).text# 使用Beautiful Soup进行数据解析# 实例化soup = BeautifulSoup(response, 'lxml')# 找到大致范围temp = soup.find('div', id='filter')# 精确查找,锁定类名为:.filter__item--level2temp = temp.select('div > ul > .filter__item--level2')[1:9]# 提取八大行政区的名字并存入NameListnameList = []# 提取八大行政区的地址并存入UrlListurlList = []# 用于进度条输出cnt = 0mb = len(temp)print('开始获取八大城区基础信息!')for i in temp:nameList.append(i.a.text)temp = 'https://cd.lianjia.com' + i.a['href']cnt += 1print('已获取数量:{} 完成度:{:.1f}%'.format(cnt, cnt * 100 / mb))urlList.append(temp)# print(nameList)# print(urlList)print('获取八大城区基础信息完成!')print('结果如下:')for i in zip(nameList, urlList):print(i)return nameList, urlListdef getHouseAreaAndNum(nameList, urlList):''':param urlList: 八大城区的网址列表:param nameList: 八大城区的名称:return: 返回每个城区的租房区域划分情况、挂网租房数量'''# 每个行政区的租房区域划分情况和挂网租房数量# 1、租房区域划分情况# 2、挂网租房数量# 遍历每一个城区,获取其中的信息,存入字典areaDict = {}cnt = 0for i in urlList:# 存放每个城区下区域划分的网址areaUrl = []# 存放每个城区下的区域划分areaName = []# 对网址进行请求response = requests.get(url=i, headers=headers).text# 实例化soup = BeautifulSoup(response, 'lxml')# 因为我们还要存下 川师前面的C 以及 东客站前面的 D,所以这里class_两个都可以print('开始获取当前城区:{} 区域划分情况!'.format(nameList[cnt]))# 1、获取每个划分城区的名称和网址temp = soup.find_all('li', class_=['filter__item--title', 'filter__item--level3'])[1:]rt = ''flag = 1# 用于进度条输出cntt = 0for j in temp:strr = j.textif strr >= 'a' and strr <= 'z':# 字母转换为大写rt = strr.upper()flag = 0else:# 如果不是 'a' - 'z' 就是正常获取地址 以及将 'a' - 'z' 前缀加到区域名前areaUrl.append('https://cd.lianjia.com' + j.a['href'])strr = strr.strip('\n')if flag == 0:rt = rt + strrflag = 1areaName.append(rt)else:areaName.append(strr)cntt += 1print("已获取数量:{} 完成度:{:.1f}%".format(cntt, cntt * 100 / len(temp)))print('获取当前城区:{} 区域划分情况完成!'.format(nameList[cnt]))# 2、获取完当前城区的划分区域和具体网址后,对具体的划分区域进行请求,获取其中的租房数量print('开始获取当前城区:{} 每个划分区域的挂网租房数量!'.format(nameList[cnt]))# 存放每个城区下区域划分的租房数量areaNum = []# 用于进度条输出cntt = 0for j in areaUrl:newResponse = requests.get(url=j, headers=headers).textsoup = BeautifulSoup(newResponse, 'lxml')temp = soup.find('span', class_='content__title--hl')areaNum.append(int(temp.text))cntt += 1print("已获取数量:{} 完成度:{:.1f}%".format(cntt, cntt * 100 / len(areaUrl)))print('获取当前城区:{} 每个划分区域的挂网租房数量完成!'.format(nameList[cnt]))areaDict[nameList[cnt]] = (areaName, areaNum)cnt += 1print('总共:已获取数量:{} 完成度:{:.1f}%'.format(cnt, cnt * 100 / len(urlList)))print('所有城区的租房区域划分情况和挂网租房数量,获取完成!')print('结果如下:')# 处理获取结果,并存入csv文件total = []for key, val in areaDict.items():total.append(sum(val[1]))myDF = pd.DataFrame(areaDict)myDF.loc['2'] = totalmyDF.index = ['当前城区区域划分情况', '当前城区区域划分挂网租房数量(单位:套)', '当前城区总挂网租房数量(单位:套)']print(myDF)myDF.to_csv('test.csv')print('结果已存入csv文件!')nameList, urlList = getBasicInfomation()
getHouseAreaAndNum(nameList, urlList)

步骤二、三

# -*- coding: utf-8 -*-'''
导入各种包,其中:
re.findall用来进行正则匹配
csv用来写csv文件
asyncio和aiohttp用来配合进行异步协程爬虫开发
time用来记录运行时间
logging用来显示错误日志
'''
from re import findall
import csv
import asyncio
import aiohttp
import time
import logging#定义基本url和行政区域列表
baseurl = "https://cd.lianjia.com/zufang"
block_list = ["锦江", "青羊", "武侯", "高新", "成华", "金牛", "天府新区", "高新西"]
#定义session和最大允许开启的协程数量,这个数越大,爬的越快
session = None
semaphore = asyncio.Semaphore(8)'''
这个函数定义了一个基本的用来实现一个使用get方法获取目标网页html文本的接口,相当于requests.get
input: A URL
output: This URL's HTML
'''
async def get(url):async with semaphore:try:logging.info('Getting %s',url)async with session.get(url) as response:return await response.text()except aiohttp.ClientError:logging.error('Error occurred while getting %s',url,exc_info=True)#这个函数用来获取每个行政分区对应的URL
def get_blockurls(html):result = []for block in block_list:block_url = findall(r'href="/zufang(.*?)"  >'+block, html)[0]result.append(block_url)return result#这个函数用来获取子区域的区域名
def get_subblock(html):result = []html = html.replace("\n","").replace("\r","").replace("\t","").replace(" ","")temp = findall(r'--level3"><ahref="/zufang(.*?)</a>', html)for t in temp:result.append(t.split('">')[1])return result#这个函数用来获取每个区域的房间数量
def get_roomnum(html):result = 0result = findall(r'content__title--hl">(.*?)</span>', html)[0]return result#这个函数获得各个房间的URL
async def get_roomurls(html, num):result = []pagenum = int((num - (num%30))/30) + 1html = html.replace("\n","").replace("\r","").replace("\t","").replace(" ","")urls = findall(r'class="content__list--item--aside"target="_blank"href="/zufang(.*?)"title="', html)for u in urls:result.append(baseurl+u)for p in range(2,pagenum+1):html = await get(baseurl+"/pg"+str(p)+"/#contentList")if not html: continuehtml = html.replace("\n", "").replace("\r","").replace("\t","").replace(" ","")urls = findall(r'class="content__list--item--aside"target="_blank"href="/zufang(.*?)"title="', html)for u in urls:result.append(baseurl+u)return result#这个函数通过正则读出HTML中的信息,并写入文件
async def get_roommessage(html, bname, w2):result = {'village':'','style':'','time':'','base':[],'pay':[],'install':[]}html = html.replace("\n","").replace("\r","").replace("\t","")subname = findall(r'此房源位于成都(.*?)的',html)[0].replace(bname,"")basemessage = findall(r'<p class="content__title">(.*?)</p>', html)[0].split('·')[1]result['village'] = basemessage.split(' ')[0]result['style'] = basemessage.split(' ')[1]result['time'] = findall(r'房源维护时间:(.*?)        <!--', html)[0]roommessage = findall(r'<li class="fl oneline">(.*?)</li>', html)for m in roommessage:try:result['base'].append(m.split(':')[1])except:passresult['pay'].append(findall(r'<li class="table_col font_gray">(.*?)</li>',html)[0])result['pay'].append(findall(r'<li class="table_col font_orange">(.*?)</li>',html)[0])result['pay'].append(findall(r'<li class="table_col">(.*?)</li>',html)[5])html = html.replace(" ","").replace("(","")install = findall(r'</li><liclass="(.*?)"><istyle="background-image:urlhttps://image1',html)for i in install:if 'flonelinefacility_no' in i:result['install'].append('0')else:result['install'].append('1')w2.writerow([bname, subname, result['village'], result['style'], result['time'],result['base'][0],result['base'][1],result['base'][2],result['base'][3],result['base'][4],result['base'][5],result['base'][6],result['base'][7],result['base'][8],result['base'][9],result['base'][10],result['base'][11],result['base'][12],result['pay'][0],result['pay'][1],result['pay'][2],result['install'][0],result['install'][1],result['install'][2],result['install'][3],result['install'][4],result['install'][5],result['install'][6],result['install'][7],result['install'][8],result['install'][9]])async def get_rooms(html, num, bname, w2):#根据数量获取指定数量的房间urlsif num < 1000:room_urls = await get_roomurls(html, num)else:room_urls = await get_roomurls(html, 1000)if not room_urls: returnfor u in room_urls:room_r = await get(u)   #爬取每个房URL的HTMLif not room_r:continuetry:room_message = await get_roommessage(room_r, bname, w2)    #筛选并写入每个房间的信息except:passasync def geturls(block, bname):blockurl = baseurl + blockblock_r = await get(blockurl)sub_blocks = get_subblock(block_r)return sub_blocksasync def get_message_main(block, bname, w1, w2):print("运行了main一次")blockurl = baseurl + block          #拼接成区域的完整URLblock_r = await get(blockurl)       #获取这个URL的HTMLroom_num = get_roomnum(block_r)     #获取每个区域的房间数量# w1.writerow([bname , room_num])     #写入文件result = await get_rooms(block_r, int(room_num), bname, w2)   #爬取每个区域的房间async def main():global session                      #将session扩展为全局变量session = aiohttp.ClientSession()   #初始化获得一个session#创建文件,写入表头# f1 = open('file1.csv','w',encoding='utf-8')f2 = open('file2.csv','w',encoding='utf-8')# w1 = csv.writer(f1)w2 = csv.writer(f2)# w1.writerow(['行政区域','挂网租房数量'])w2.writerow(['行政区域','区域','小区','房型','房源维护时间','面积','朝向','维护','入住','楼层','电梯','车位','用水','用电','燃气','采暖','租期','看房','付款方式','租金','押金','洗衣机','空调','衣柜','电视','冰箱','热水器','床','暖气','宽带','天然气'])#获取每个区域的urlbase_r = await get(baseurl)block_urls = get_blockurls(base_r)#创建并运行协程indextasks = [asyncio.ensure_future(get_message_main(block,bname,w1,w2)) for block,bname in zip(block_urls,block_list)]result = await asyncio.gather(*indextasks)#关闭文件和session# f1.close()f2.close()await session.close()
if __name__ == '__main__':start = time.time()print("Start at: " , start)#运行main函数asyncio.get_event_loop().run_until_complete(main())end  = time.time()print("End at:   " , end)print("Time cost:" , end-start)

Python大作业-爬取成都链家租房信息(大作业)源码相关推荐

  1. 爬取南京链家租房信息

    爬取南京链家租房信息 代码如下 代码片. import requests from lxml import etree if name == "main": #设置一个通用URL模 ...

  2. 爬取广州链家租房信息,并用tableau进行数据分析

    在外工作,难免需要租房子,而链家是现在比较火的一个租房网站,本文章主要是爬取链家在广州的租房信息,并且进行简单的数据分析. 数据采集 如图所示,我们需要的信息主要是存放在这个标签里面,我们把信息采集下 ...

  3. python用scrapy爬取58同城的租房信息

    上篇我们用了beautifulsoup4做了简易爬虫,本次我们用scrapy写爬虫58同城的租房信息,可以爬取下一页的信息直至最后一页. 1.scrapy的安装 这个安装网上教程比较多,也比较简单,就 ...

  4. Python爬虫教程-爬取5K分辨率超清唯美壁纸源码

    简介 壁纸的选择其实很大程度上能看出电脑主人的内心世界,有的人喜欢风景,有的人喜欢星空,有的人喜欢美女,有的人喜欢动物.然而,终究有一天你已经产生审美疲劳了,但你下定决定要换壁纸的时候,又发现网上的壁 ...

  5. 用Python爬取2020链家杭州二手房数据

    起源于数据挖掘课程设计的需求,参考着17年这位老兄写的代码:https://blog.csdn.net/sinat_36772813/article/details/73497956?utm_medi ...

  6. Python爬虫框架Scrapy入门(三)爬虫实战:爬取长沙链家二手房

    Item Pipeline介绍 Item对象是一个简单的容器,用于收集抓取到的数据,其提供了类似于字典(dictionary-like)的API,并具有用于声明可用字段的简单语法. Scrapy的It ...

  7. python爬虫--爬取链家租房信息

    python 爬虫-链家租房信息 爬虫,其实就是爬取web页面上的信息. 链家租房信息页面如下: https://gz.lianjia.com/zufang/ ## python库 Python库 1 ...

  8. Python 爬虫 之 爬取王者荣耀的英雄们所有大皮肤图片,并 json 形式保存英雄列表信息到本地

    Python 爬虫 之 爬取王者荣耀的英雄们所有大皮肤图片,并 json 形式保存英雄列表信息到本地 目录

  9. 爬取‘广州链家新房’数据并以csv形式保存。

    --本次的目标是爬取'广州链家新房'前十页的信息,具体需要爬取的信息为'楼房名字.地址.价格以及是否在售的情况',具体的代码如下. import requests,time import pandas ...

  10. Python爬虫入门 | 5 爬取小猪短租租房信息

    小猪短租是一个租房网站,上面有很多优质的民宿出租信息,下面我们以成都地区的租房信息为例,来尝试爬取这些数据. 小猪短租(成都)页面:http://cd.xiaozhu.com/   1.爬取租房标题 ...

最新文章

  1. 用jdk在cmd下运行编译java程序
  2. python UnicodeEncodeError 编码错误总结
  3. Windows如何打包Qt程序
  4. 融资租赁基础干货知识大整理
  5. SpringMVC配置类WebMvcConfigurerAdapter学习总结
  6. JSON-B非对称属性绑定
  7. html5 支持音频格式,html5中audio支持音频格式
  8. LeetCode(893)——特殊等价字符串组(JavaScript)
  9. paip.c3p0 数据库连接池 NullPointerException 的解决...
  10. txt转excel 处理数据
  11. 基本的广告法违禁词、违规词以及敏感词大全
  12. 古今地名对照总表!(按笔划数排序,强烈推荐的资料)
  13. android6.0 framework修改使用两个声卡
  14. 菲尔茨奖得主陶哲轩:瓜分数学成就 没有益处
  15. 用计算机绘制函数图像ppt,ppt怎么制作函数图
  16. 自动回复html模板邮件,outlook邮件自动回复设置
  17. matlab 效度,量表的信度、效度检验方法小结
  18. API通达信接口如何获取股票实时行情?
  19. 纹波(ripple)的定义
  20. iconfont字体图标以及css字体图标在线制作和使用(推荐)

热门文章

  1. 星际迷航4之抢救未来
  2. Period、Duration计算时间间隔
  3. 全国DNS服务器IP地址【电信、网通、铁通】。
  4. 【信号处理】扩展卡尔曼滤波EKF(Matlab代码实现)
  5. 区块链研究实验室-首次提出如何确保区块链分片技术的数据完整性
  6. 业余10—解决只能打开网页不能打开QQ或视频软件问题
  7. RequestHead详解
  8. 计算机包含几个语素几个词,英语一词有几个语素
  9. HTML篇三——(1)
  10. Unknown host 'dl.google.com'. You may need to adjust the proxy settings in Gradle.