使用Python來爬取二手房源數據,並保存表格,實現數據分析! 軟體環境 Python 3.8 Pycharm 代碼展示 模塊 # 數據請求模塊 --> 第三方模塊, 需要安裝 pip install requests import requests # 解析數據模塊 --> 第三方模塊, 需要安裝 ...
使用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.lianjia.com/ershoufang/' # 完整源碼,視頻講解直接+這個扣裙:279199867 免費領取
發送請求
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).text selector = 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) # 總計耗時: 9 print('總計耗時:', use_time)