小学妹刚毕业没地方住想来借宿,于是我连夜用Python给她找了个好房子,我真是太机智了

news/2024/12/2 7:01:05/

事情是这样的,小学妹刚毕业参加工作,人生地不熟的,因为就在我附近上班,所以想找我借宿。。。

想什么呢,都不给住宿费,想免费住?于是我用Python连夜给她找了个单间,自己去住吧!

软件环境

Python 3.8

Pycharm

代码展示

模块

# 数据请求模块 --> 第三方模块, 需要安装 pip install requests
import requests
# 解析数据模块 --> 第三方模块, 需要安装 pip install parsel
import parsel
# csv模块
import csv

创建文件

f = open('data.csv', mode='w', encoding='utf-8', newline='')
csv_writer = csv.DictWriter(f, fieldnames=['标题','小区','区域','售价','单价','户型','面积','朝向','装修','楼层','年份','建筑类型','详情页',
])
csv_writer.writeheader()

发送请求, 模拟浏览器 对于 url地址 发送请求

模拟浏览器

headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36'
}

请求网址/网站

url = 'https://cs.***.com/ershoufang/'

发送请求

response = requests.get(url=url, headers=headers)
# <Response [200]> 响应对象 200 状态码 表示请求成功
print(response)

获取数据, 获取网页源代码 <获取服务器返回响应数据>

解析数据, 提取我们想要的数据内容

解析方法:

  • re: 对于字符串数据直接进行解析提取

  • css: 根据标签属性提取数据内容

  • xpath: 根据标签节点提取数据内容

使用css: 根据标签属性提取数据内容

把获取到html字符串数据, 转成可解析对象

selector = parsel.Selector(response.text)

获取所有房源信息所在li标签

lis = selector.css('.sellListContent li.clear')

for循环遍历

for li in lis:"""提取具体房源信息: 标题 / 价格 / 位置 / 户型....title a --> 表示定位class类名为title下面a标签"""title = li.css('.title a::text').get()  # 标题info_list = li.css('.positionInfo a::text').getall()area = info_list[0]  # 小区名字area_1 = info_list[1]  # 地区totalPrice = li.css('.totalPrice span::text').get()  # 售价unitPrice = li.css('.unitPrice span::text').get().replace('元/平', '').replace(',', '')  # 单价houseInfo = li.css('.houseInfo::text').get().split(' | ')  # 信息houseType = houseInfo[0]  # 户型houseArea = houseInfo[1].replace('平米', '')  # 面积houseFace = houseInfo[2]  # 朝向fitment = houseInfo[3]  # 装修fool = houseInfo[4]  # 楼层if len(houseInfo) == 7 and '年' in houseInfo[5]:year = houseInfo[5].replace('年建', '')else:year = ''house = houseInfo[-1]  # 建筑类型href = li.css('.title a::attr(href)').get()  # 详情页dit = {'标题': title,'小区': area,'区域': area_1,'售价': totalPrice,'单价': unitPrice,'户型': houseType,'面积': houseArea,'朝向': houseFace,'装修': fitment,'楼层': fool,'年份': year,'建筑类型': house,'详情页': href,}csv_writer.writerow(dit)print(dit)# print(title, area, area_1, totalPrice, unitPrice, houseType, houseArea, houseFace, fitment, fool, year, house, href)

多线程

导入模块

import requests
import parsel
import re
import csv
# 线程池模块
import concurrent.futures
import time

发送请求函数

def get_response(html_url)::param html_url:
:return:
"""
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
}
response = requests.get(url=html_url, headers=headers)
return response

获取数据函数

def get_content(html_url):""":param html_url::return:"""response = get_response(html_url)html_data = get_response(link).textselector = parsel.Selector(response.text)select = parsel.Selector(html_data)lis = selector.css('.sellListContent li')content_list = []for li in lis:title = li.css('.title a::text').get()  # 标题area = '-'.join(li.css('.positionInfo a::text').getall())  # 小区Price = li.css('.totalPrice span::text').get()  # 总价Price_1 = li.css('.unitPrice span::text').get().replace('元/平', '')  # 单价houseInfo = li.css('.houseInfo::text').get()  # 信息HouseType = houseInfo.split(' | ')[0]  # 户型HouseArea = houseInfo.split(' | ')[1].replace('平米', '')  # 面积direction = houseInfo.split(' | ')[2].replace(' ', '')  # 朝向renovation = houseInfo.split(' | ')[3]  # 装修floor_info = houseInfo.split(' | ')[4]floor = floor_info[:3]  # 楼层floor_num = re.findall('(\d+)层', floor_info)[0]  # 层数BuildingType = houseInfo.split(' | ')[-1]string = select.css('.comments div:nth-child(7) .comment_text::text').get()href = li.css('.title a::attr(href)').get()  # 详情页if len(houseInfo.split(' | ')) == 6:date = 'None'else:date = houseInfo.split(' | ')[5].replace('年建', '')  # 日期print(string)dit = {'标题': title,'内容': string,'小区': area,'总价': Price,'单价': Price_1,'户型': HouseType,'面积': HouseArea,'朝向': direction,'装修': renovation,'楼层': floor,'层数': floor_num,'建筑日期': date,'建筑类型': BuildingType,'详情页': href,}content_list.append(dit)return content_list

主函数

def main(page):""":param page::return:"""print(f'===============正在采集第{page}页的数据内容===============')url = f'https:///ershoufang/yuelu/p{page}/'content_list = get_content(html_url=url)for content in content_list:csv_writer.writerow(content)if __name__ == '__main__':time_1 = time.time()link = 'http://******/article/149'# 创建文件f = open('data多线程.csv', mode='a', encoding='utf-8', newline='')csv_writer = csv.DictWriter(f, fieldnames=['标题','内容','小区','总价','单价','户型','面积','朝向','装修','楼层','层数','建筑日期','建筑类型','详情页',])csv_writer.writeheader()# 线程池执行器 max_workers 最大线程数exe = concurrent.futures.ThreadPoolExecutor(max_workers=10)for page in range(1, 11):exe.submit(main, page)exe.shutdown()time_2 = time.time()use_time = int(time_2 - time_1)# 总计耗时: 9print('总计耗时:', use_time)

最后

好了,今天分享就到这里,我要假装不在家,不然小学妹又来找我!


http://www.ppmy.cn/news/79534.html

相关文章

我3年前写的博客,又被别人抄去发论文了,该论文整个正文部分几乎直接照抄我的博客

我想说每一篇原创博客都是作者的心血&#xff0c;有时候写一篇博客也许会花一天&#xff0c;甚至好几天的时间&#xff0c;尊重原创&#xff0c;营造好的环境&#xff0c;才有可能出现更多优质的博文&#xff0c;而不是到处都是抄来抄去的低质量水文。 前几天接到来自粉丝的私信…

pdf怎么拆分成一页一页的?办公常备工具说明

PDF&#xff08;Portable Document Format&#xff09;是一种用于创建和共享文档的文件格式。它由Adobe Systems开发&#xff0c;并已成为电子文档的通用格式。PDF文件可以包含文本、图像、表格、超链接和其他多媒体内容&#xff0c;使其成为一种非常方便的文件格式。 然而&…

Vulkan Tutorial 4

目录 11 framebuffer 12 命令缓冲区 13 Rendering and presentation 信号量 栅栏 创建同步对象 等待上一帧 从交换链获取图像 提交命令缓冲区 子通道依赖 Presentation 14 Frames in flight 15 Swap chain recreation 重新创建交换链 11 framebuffer 我们已经将…

【1377. T 秒后青蛙的位置】

来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 给你一棵由 n 个顶点组成的无向树&#xff0c;顶点编号从 1 到 n。青蛙从 顶点 1 开始起跳。规则如下&#xff1a; 在一秒内&#xff0c;青蛙从它所在的当前顶点跳到另一个 未访问 过的顶点&#xf…

halcon模板匹配之shape/ncc模板匹配参数解释说明

注&#xff1a;转载请保留原文地址https://blog.csdn.net/baidu_36363174/article/details/105846684 参数&#xff1a; NumLevels 金字塔层数越大&#xff0c;计算次数越快。【但采样过程中&#xff0c;图像信息减少&#xff0c;匹配的精确性会降低&#xff0c;特别是层数特别…

JavaScript 基础 DOM (三)

日期对象 实例化 获得当前时间 const date new Date() 获得指定时间 const date1 new Date( 指定时间) 方法 // 1. 实例化const date new Date();// 2. 调用时间对象方法// 通过方法分别获取年、月、日&#xff0c;时、分、秒const year date.getFullYear(); // 四位年份 时…

Netty 源码分析系列(十八)一行简单的writeAndFlush都做了哪些事?

文章目录 前言源码分析ctx.writeAndFlush 的逻辑writeAndFlush 源码ChannelOutBoundBuff 类addMessage 方法addFlush 方法AbstractNioByteChannel 类 小结 前言 对于使用netty的小伙伴来说&#xff0c;我们想通过服务端往客户端发送数据&#xff0c;通常我们会调用ctx.writeAn…

3年自动化测试这水平?我还不如去招应届生...

公司前段缺人&#xff0c;也面了不少测试&#xff0c;结果竟然没有一个合适的。一开始瞄准的就是中级的水准&#xff0c;也没指望来大牛&#xff0c;提供的薪资在10-20k&#xff0c;面试的人很多&#xff0c;但平均水平很让人失望。看简历很多都是3年工作经验&#xff0c;但面试…