目录
抓取链家前十页的数据
链家网址:长沙房产网_长沙房地产_长沙房产门户(长沙链家网)
计算均价和总价
import time from selenium import webdriver from selenium.webdriver.common.by import By driver = webdriver.Chrome() driver.get("https://cs.lianjia.com/zufang/rs岳麓区/") # 总价 total = 0 # 记录房间个数 size = 0 for i in range(2): elements = driver.find_elements(By.CSS_SELECTOR, '.content__list--item--main') print(f"第{i+1}页的数据:") for el in elements: # 获取租房标题 name = el.find_element(By.CSS_SELECTOR, '.content__list--item--title a').text # 判断是否包含独栋信息 if name.__contains__("独栋"): continue # 获取租房的价格 price = el.find_element(By.CSS_SELECTOR, '.content__list--item-price em').text print(f"name={name},price={price}") total += float(price) # 记录房间的个数 size += len(elements) # 点击下一页 driver.find_element(By.CSS_SELECTOR,'a.next').click() # 模拟睡眠6秒 time.sleep(2) print(f"总价:{total},岳麓区的租房均价为:{total/size}")
计算的类型(整租,合租)
str = """ name=整租·万科里金域国际 4室2厅 南,price=4500 name=独栋·魔方公寓 长沙航天溪湖店 连锁公寓直租无中介费 1室1厅,price=1800 name=整租·潇湘奥林匹克花园 1室1厅 南,price=2200 name=合租·达美美立方 5居室 复式 南卧,price=999 name=整租·万科里金域国际 3室2厅 南,price=3400 """ # 计算的类型(整租,合租) print("整租:", str.count("整租")) print("合租:", str.count("合租"))
计算的房型
由于在爬取的数据中存在“居室”
和“室”
的区别,所以请将所有的“居室”
数据替换成“室”
。
str = """ name=整租·万科里金域国际 4室2厅 南,price=4500 name=独栋·魔方公寓 长沙航天溪湖店 连锁公寓直租无中介费 1室1厅,price=1800 name=整租·潇湘奥林匹克花园 1室1厅 南,price=2200 name=合租·达美美立方 5居室 复式 南卧,price=999 name=整租·万科里金域国际 3室2厅 南,price=3400 """ import re import collections st = str.replace('居室','室') rs = re.findall(r'\d室',st) print(rs) print(collections.Counter(rs))
完整可执行且标注代码
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://cs.lianjia.com/zufang/rs岳麓区/")
# 总价
total = 0
# 记录房间个数
size = 0
for i in range(2):
elements = driver.find_elements(By.CSS_SELECTOR, '.content__list--item--main')
print(f"第{i+1}页的数据:")
for el in elements:
# 获取租房标题
name = el.find_element(By.CSS_SELECTOR, '.content__list--item--title a').text
# 判断是否包含独栋信息
if name.__contains__("独栋"):
continue
# 获取租房的价格
price = el.find_element(By.CSS_SELECTOR, '.content__list--item-price em').text
print(f"name={name},price={price}")
total += float(price)
# 顶部滚到底部
driver.execute_script('window.scrollTo(0,document.body.scrollHeight);')
# 记录房间的个数
size += len(elements)
# 点击下一页
driver.find_element(By.CSS_SELECTOR,'a.next').click()
# 模拟睡眠6秒
time.sleep(2)
print(f"总价:{total},岳麓区的租房均价为:{total/size}")
抓取boss直聘前十页的数据
boss直聘网址:BOSS直聘-找工作上BOSS直聘直接谈!招聘求职找工作!
抓取boss直聘前十页的数据
其中参数city=101020100
是中国天气网全城市代码weather_cityId
。
from selenium import webdriver from selenium.webdriver.common.by import By import time driver = webdriver.Chrome() driver.get("https://www.zhipin.com/web/geek/job?query=java&city=101020100") jobs = [] for i in range(3): time.sleep(6) elements = driver.find_elements(By.CSS_SELECTOR, ".job-card-wrapper") for el in elements: # 获取地区 area = el.find_element(By.CSS_SELECTOR,"span.job-area").text # 获取薪酬 salary = el.find_element(By.CSS_SELECTOR,"span.salary").text print(f"area={area},salary={salary}") jobs.append({ 'area':area, 'salary':salary }) driver.find_element(By.CSS_SELECTOR,".selected+a").click() print(jobs)
将获取数据本地序列化
Python的pickle
模块是一种用于序列化(将对象转换为字节流)和反序列化(将字节流转换回对象)Python对象的工具。它可以将Python对象保存到文件中或从文件中加载对象。
pickle
模块还有其他一些有用的函数和特性。以下是一些常见的功能:
-
pickle.dumps(obj)
:将对象序列化为字节流,但不保存到文件中。 -
pickle.loads(bytes_obj)
:从字节流中加载对象,而不是从文件中加载。 -
pickle.dump(obj, file)
:将对象序列化并保存到文件中。 -
pickle.load(file)
:从文件中加载序列化的对象。
# 将获取到的结果保存到本地 p = Path("jobs.txt") p.touch() # 通过pickle.dump实现数据序列化 pickle.dump(jobs,p.open(mode="wb"))
计算每个区的需求个数与均价
# 计算每个区的需求个数与均价 jobs = pickle.load(open('jobs.txt',mode="rb")) print(jobs) areas=list(map(lambda a: "".join(re.findall(r'.*?·(.*?)·.*?',a['area'])),jobs)) print(areas) import collections rs = collections.Counter(areas) for k,v in rs.items(): print(f"【{k}】的工作岗位需求数:{v}") # 获取该区的工作集合 ps = list(filter(lambda e: e['area'].count(k) > 0, jobs)) # 获取该区的薪酬总价 total = functools.reduce(lambda a,b:a+int(b['salary'].split('-')[0]),ps,0) print(f"该区的工作入门平均薪酬:{total/len(ps)}")
完整可执行且标注代码
序列化
import json # 导入json模块,用于处理JSON数据
import time # 导入time模块,用于延时操作
from selenium import webdriver # 导入selenium的webdriver模块,用于自动化浏览器操作
from selenium.webdriver.common.by import By # 导入selenium的By模块,用于定位元素
driver = webdriver.Edge() # 初始化Edge浏览器的WebDriver实例
driver.get("") # 访问BOSS直聘网站的URL,这里需要替换为实际的URL
jobs = [] # 初始化一个空列表,用于存储抓取的职位信息
# try:
for i in range(2): # 循环两次,假设只抓取两页的数据
print(f'正在获取第{i+1}页数据') # 打印当前正在抓取的页码
time.sleep(20) # 等待20秒,让页面加载完成
items = driver.find_elements(By.CLASS_NAME,'job-card-wrapper') # 查找所有具有'job-card-wrapper'类名的元素
for item in items: # 遍历这些元素
addr = item.find_element(By.CLASS_NAME,'job-area') # 在每个元素中查找具有'job-area'类名的元素
price = item.find_element(By.CLASS_NAME,'salary') # 在每个元素中查找具有'salary'类名的元素
print(addr.text, price.text) # 打印地址和薪资信息
jobs.append({ # 将地址和薪资信息添加到jobs列表中
'area': addr.text,
'salary': price.text
})
# 它表示选取所有紧接在类为"selected"的元素后面的同级元素中的标签为"a"的元素
driver.find_element(By.CSS_SELECTOR,'.selected+a').click() # 点击下一页的链接
print(jobs) # 打印所有抓取到的职位信息
# 序列化
with open("jobs.json","w",encoding='utf-8') as fp: # 打开或创建一个名为"jobs.json"的文件,准备写入
# ensure_ascii=False (关闭默认阿斯玛写入方式)
json.dump(jobs, fp, ensure_ascii=False, indent=2) # 将jobs列表中的数据序列化为JSON格式,并写入文件,格式化输出
# except Exception as ex:
# print(ex) # 这行代码被注释掉了,它用于捕获并打印异常信息
反序列化
import json # 导入json模块,用于处理JSON数据
import re # 导入re模块,用于正则表达式操作
from collections import Counter # 导入Counter类,用于计数
jbos = [] # 初始化一个空列表,用于存储从JSON文件中加载的职位信息
# 反序列化
with open('jbos.json', 'r', encoding='utf-8') as fp: # 打开名为'jbos.json'的文件,准备读取
jbos = json.load(fp) # 从文件中加载JSON数据到jbos列表中
print(jbos) # 打印加载的职位信息列表
# 提取区名
def extract_district(job: dict): # 定义一个函数,用于从职位信息中提取区域名称
match = re.search(r'·([^·]+区)·', job['area']) # 使用正则表达式匹配职位区域名称
if match: # 如果匹配成功
return match.group(1) # 返回匹配到的区域名称
return "" # 如果没有匹配到,返回空字符串
arears = list(map(extract_district, jbos)) # 使用map函数和extract_district函数,将jbos列表中的每个职位映射到其区域名称,生成一个新的列表arears
print(arears) # 打印提取的区域名称列表
# 统计每个区出现的次数
dict = Counter(arears) # 使用Counter类统计arears列表中每个区域出现的次数
print(dict) # 打印区域出现次数的统计结果
for k, v in dict.items(): # 遍历统计结果中的每个区域及其出现次数
print(f'{k}有{v}条招聘信息') # 打印每个区域的招聘信息数量
total = 0 # 初始化总薪水变量
count = 0 # 初始化计数器
for job in jbos: # 遍历所有职位信息
if job['area'].__contains__(k): # 如果职位区域包含当前区域
total = total + int(re.search(r'(\d+?)-', job['salary']).group(1)) # 将薪水转换为整数并累加到总薪水
count += 1 # 增加计数器
print(f'平均薪水{total}') # 打印当前区域的平均薪水