使用Python來爬取二手房源數(shù)據(jù),并保存表格,實(shí)現(xiàn)數(shù)據(jù)分析!
軟件環(huán)境
Python 3.8
Pycharm
代碼展示
模塊
# 數(shù)據(jù)請求模塊 --> 第三方模塊, 需要安裝 pip install requests import requests # 解析數(shù)據(jù)模塊 --> 第三方模塊, 需要安裝 pip install parsel import parsel # csv模塊 import csv
?
創(chuàng)建文件
f = open('data.csv', mode='w', encoding='utf-8', newline='') csv_writer = csv.DictWriter(f, fieldnames=[ '標(biāo)題', '小區(qū)', '區(qū)域', '售價(jià)', '單價(jià)', '戶型', '面積', '朝向', '裝修', '樓層', '年份', '建筑類型', '詳情頁', ]) csv_writer.writeheader()
?
發(fā)送請求, 模擬瀏覽器 對于 url地址 發(fā)送請求
模擬瀏覽器
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' }
?
請求網(wǎng)址/網(wǎng)站
url = 'https://cs.lianjia.com/ershoufang/' # 完整源碼,視頻講解直接+這個(gè)扣裙:279199867 免費(fèi)領(lǐng)取
?
發(fā)送請求
response = requests.get(url=url, headers=headers) # <Response [200]> 響應(yīng)對象 200 狀態(tài)碼 表示請求成功 print(response)
?
獲取數(shù)據(jù), 獲取網(wǎng)頁源代碼 <獲取服務(wù)器返回響應(yīng)數(shù)據(jù)>
解析數(shù)據(jù), 提取我們想要的數(shù)據(jù)內(nèi)容
解析方法:
-
re: 對于字符串?dāng)?shù)據(jù)直接進(jìn)行解析提取
-
css: 根據(jù)標(biāo)簽屬性提取數(shù)據(jù)內(nèi)容
-
xpath: 根據(jù)標(biāo)簽節(jié)點(diǎn)提取數(shù)據(jù)內(nèi)容
使用css: 根據(jù)標(biāo)簽屬性提取數(shù)據(jù)內(nèi)容
把獲取到html字符串?dāng)?shù)據(jù), 轉(zhuǎn)成可解析對象
selector = parsel.Selector(response.text)
?
獲取所有房源信息所在li標(biāo)簽
lis = selector.css('.sellListContent li.clear')
?
for循環(huán)遍歷
for li in lis: """
提取具體房源信息: 標(biāo)題 / 價(jià)格 / 位置 / 戶型... .title a --> 表示定位class類名為title下面a標(biāo)簽 """ title = li.css('.title a::text').get() # 標(biāo)題 info_list = li.css('.positionInfo a::text').getall() area = info_list[0] # 小區(qū)名字 area_1 = info_list[1] # 地區(qū) totalPrice = li.css('.totalPrice span::text').get() # 售價(jià) unitPrice = li.css('.unitPrice span::text').get().replace('元/平', '').replace(',', '') # 單價(jià) 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 = { '標(biāo)題': title, '小區(qū)': area, '區(qū)域': area_1, '售價(jià)': totalPrice, '單價(jià)': 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)
?
多線程
導(dǎo)入模塊
import requests import parsel import re import csv # 線程池模塊 import concurrent.futures import time
?
發(fā)送請求函數(shù)
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
?
獲取數(shù)據(jù)函數(shù)
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() # 標(biāo)題 area = '-'.join(li.css('.positionInfo a::text').getall()) # 小區(qū) Price = li.css('.totalPrice span::text').get() # 總價(jià) Price_1 = li.css('.unitPrice span::text').get().replace('元/平', '') # 單價(jià) 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] # 層數(shù) 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 = { '標(biāo)題': title, '內(nèi)容': string, '小區(qū)': area, '總價(jià)': Price, '單價(jià)': Price_1, '戶型': HouseType, '面積': HouseArea, '朝向': direction, '裝修': renovation, '樓層': floor, '層數(shù)': floor_num, '建筑日期': date, '建筑類型': BuildingType, '詳情頁': href, } content_list.append(dit) return content_list
?
主函數(shù)文章來源:http://www.zghlxwxcb.cn/news/detail-445477.html
def main(page): """ :param page: :return: """ print(f'===============正在采集第{page}頁的數(shù)據(jù)內(nèi)容===============') 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' # 創(chuàng)建文件 f = open('data多線程.csv', mode='a', encoding='utf-8', newline='') csv_writer = csv.DictWriter(f, fieldnames=[ '標(biāo)題', '內(nèi)容', '小區(qū)', '總價(jià)', '單價(jià)', '戶型', '面積', '朝向', '裝修', '樓層', '層數(shù)', '建筑日期', '建筑類型', '詳情頁', ]) csv_writer.writeheader() # 線程池執(zhí)行器 max_workers 最大線程數(shù) 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) # 總計(jì)耗時(shí): 9 print('總計(jì)耗時(shí):', use_time)
?文章來源地址http://www.zghlxwxcb.cn/news/detail-445477.html
到了這里,關(guān)于Python多線程爬取鏈家房源,保存表格,實(shí)現(xiàn)數(shù)據(jù)可視化分析!的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!