Python3 爬虫实战 — 安居客武汉二手房【requests、Beautiful Soup、CSV】
- 爬取時(shí)間:2019-10-09
- 爬取難度:★★☆☆☆☆
- 請(qǐng)求鏈接:https://wuhan.anjuke.com/sale/
- 爬取目標(biāo):爬取武漢二手房每一條售房信息,包含地理位置、價(jià)格、面積等,保存為 CSV 文件
- 涉及知識(shí):請(qǐng)求庫 requests、解析庫 Beautiful Soup、CSV 文件儲(chǔ)存、列表操作、分頁判斷
- 完整代碼:https://github.com/TRHX/Python3-Spider-Practice/tree/master/BasicTraining/anjuke
- 其他爬蟲實(shí)戰(zhàn)代碼合集(持續(xù)更新):https://github.com/TRHX/Python3-Spider-Practice
- 爬蟲實(shí)戰(zhàn)專欄(持續(xù)更新):https://itrhx.blog.csdn.net/article/category/9351278
文章目錄
- 【1x00】頁面整體分析
- 【2x00】解析模塊
- 【3x00】循環(huán)爬取模塊
- 【4x00】數(shù)據(jù)儲(chǔ)存模塊
- 【5x00】完整代碼
- 【6x00】數(shù)據(jù)截圖
- 【7x00】程序不足的地方
【1x00】頁面整體分析
分析 安居客武漢二手房頁面,這次爬取實(shí)戰(zhàn)準(zhǔn)備使用 BeautifulSoup 解析庫,熟練 BeautifulSoup 解析庫的用法,注意到該頁面與其他頁面不同的是,不能一次性看到到底有多少頁,以前知道一共有多少頁,直接一個(gè)循環(huán)爬取就行了,雖然可以通過改變 url 來嘗試找到最后一頁,但是這樣就顯得不程序員了?,因此可以通過 BeautifulSoup 解析 下一頁按鈕,提取到下一頁的 url,直到?jīng)]有 下一頁按鈕 這個(gè)元素為止,從而實(shí)現(xiàn)所有頁面的爬取,剩下的信息提取和儲(chǔ)存就比較簡單了
【2x00】解析模塊
分析頁面,可以發(fā)現(xiàn)每條二手房信息都是包含在 <li> 標(biāo)簽內(nèi)的,因此可以使用 BeautifulSoup 解析頁面得到所有的 <li> 標(biāo)簽,然后再循環(huán)訪問每個(gè) <li> 標(biāo)簽,依次解析得到每條二手房的各種信息
【3x00】循環(huán)爬取模塊
前面已經(jīng)分析過,該網(wǎng)頁是無法一下就能看到一共有多少頁的,嘗試找到最后一頁,發(fā)現(xiàn)一共有50頁,那么此時(shí)就可以搞個(gè)循環(huán),一直到第50頁就行了,但是如果有一天頁面數(shù)增加了呢,那么代碼的可維護(hù)性就不好了,我們可以觀察 下一頁按鈕 ,當(dāng)存在下一頁的時(shí)候,是 <a> 標(biāo)簽,并且?guī)в邢乱豁摰?URL,不存在下一頁的時(shí)候是 <i> 標(biāo)簽,因此可以寫個(gè) if 語句,判斷是否存在此 <a> 標(biāo)簽,若存在,表示有下一頁,然后提取其 href 屬性并傳給解析模塊,實(shí)現(xiàn)后面所有頁面的信息提取,此外,由于安居客有反爬系統(tǒng),我們還可以利用 Python中的 random.randint() 方法,在兩個(gè)數(shù)值之間隨機(jī)取一個(gè)數(shù),傳入 time.sleep() 方法,實(shí)現(xiàn)隨機(jī)暫停爬取
【4x00】數(shù)據(jù)儲(chǔ)存模塊
數(shù)據(jù)儲(chǔ)存比較簡單,將每個(gè)二手房信息組成一個(gè)列表,依次寫入到 anjuke.csv 文件中即可
results = [title, layout, cover, floor, year, unit_price, total_price, keyword, address, details_url] with open('anjuke.csv', 'a', newline='', encoding='utf-8-sig') as f:w = csv.writer(f)w.writerow(results)【5x00】完整代碼
# ============================================= # --*-- coding: utf-8 --*-- # @Time : 2019-10-09 # @Author : TRHX # @Blog : www.itrhx.com # @CSDN : https://blog.csdn.net/qq_36759224 # @FileName: anjuke.py # @Software: PyCharm # =============================================import requests import time import csv import random from bs4 import BeautifulSoupheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36' }def parse_pages(url, num):response = requests.get(url=url, headers=headers)soup = BeautifulSoup(response.text, 'lxml')result_list = soup.find_all('li', class_='list-item')# print(len(result_list))for result in result_list:# 標(biāo)題title = result.find('a', class_='houseListTitle').text.strip()# print(title)# 戶型layout = result.select('.details-item > span')[0].text# print(layout)# 面積cover = result.select('.details-item > span')[1].text# print(cover)# 樓層floor = result.select('.details-item > span')[2].text# print(floor)# 建造年份year = result.select('.details-item > span')[3].text# print(year)# 單價(jià)unit_price = result.find('span', class_='unit-price').text.strip()# print(unit_price)# 總價(jià)total_price = result.find('span', class_='price-det').text.strip()# print(total_price)# 關(guān)鍵字keyword = result.find('div', class_='tags-bottom').text.strip()# print(keyword)# 地址address = result.find('span', class_='comm-address').text.replace(' ', '').replace('\n', '')# print(address)# 詳情頁urldetails_url = result.find('a', class_='houseListTitle')['href']# print(details_url)results = [title, layout, cover, floor, year, unit_price, total_price, keyword, address, details_url]with open('anjuke.csv', 'a', newline='', encoding='utf-8-sig') as f:w = csv.writer(f)w.writerow(results)# 判斷是否還有下一頁next_url = soup.find_all('a', class_='aNxt')if len(next_url) != 0:num += 1print('第' + str(num) + '頁數(shù)據(jù)爬取完畢!')# 3-60秒之間隨機(jī)暫停time.sleep(random.randint(3, 60))parse_pages(next_url[0].attrs['href'], num)else:print('所有數(shù)據(jù)爬取完畢!')if __name__ == '__main__':with open('anjuke.csv', 'a', newline='', encoding='utf-8-sig') as fp:writer = csv.writer(fp)writer.writerow(['標(biāo)題', '戶型', '面積', '樓層', '建造年份', '單價(jià)', '總價(jià)', '關(guān)鍵字', '地址', '詳情頁地址'])start_num = 0start_url = 'https://wuhan.anjuke.com/sale/'parse_pages(start_url, start_num)【6x00】數(shù)據(jù)截圖
【7x00】程序不足的地方
-
雖然使用了隨機(jī)暫停爬取的方法,但是在爬取了大約 20 頁的數(shù)據(jù)后依然會(huì)出現(xiàn)驗(yàn)證頁面,導(dǎo)致程序終止
-
原來設(shè)想的是可以由用戶手動(dòng)輸入城市的拼音來查詢不同城市的信息,方法是把用戶輸入的城市拼音和其他參數(shù)一起構(gòu)造成一個(gè) URL,然后對(duì)該 URL 發(fā)送請(qǐng)求,判斷請(qǐng)求返回的代碼,如果是 200 就代表可以訪問,也就是用戶輸入的城市是正確的,然而發(fā)現(xiàn)即便是輸入錯(cuò)誤,該 URL 依然可以訪問,只不過會(huì)跳轉(zhuǎn)到一個(gè)正確的頁面,沒有搞清楚是什么原理,也就無法實(shí)現(xiàn)由用戶輸入城市來查詢這個(gè)功能
總結(jié)
以上是生活随笔為你收集整理的Python3 爬虫实战 — 安居客武汉二手房【requests、Beautiful Soup、CSV】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 宏光MINI EV强力挑战者 奇瑞QQ冰
- 下一篇: Selenium 显式等待条件及其含义