最近由於工作突然變動,新的辦公地點離現在的住處很遠,必須換房子租了。
我坐上中介的小電驢,開始探索城市各處的陌生角落。
在各個租屋app之間週轉的過程中,我屬實有些焦頭爛額,因為效率真的很低下:
首先,因為跟女友住在一起,需要同時考慮兩人的上班路程,但各平台按通勤時長找房的功能都比較雞肋,有的平台不支持同時選擇多個地點,有的平台只能機械的取到離各個地點通勤時長相同的點,滿足不了使用需求。
其次,站在一個租房人的立場,租房平台實在太多了,並且各平台篩選和排序邏輯都不太一致,導致很難將相似房源的資訊進行橫向比較。
但是沒有關係,身為程式設計師,當然要用程式設計師的方法來解決問題了。於是,昨晚我用一個python腳本,獲取了某租房平台上海地區的所有房源信息,一共2w多條:
##下面就把本次爬數據的整個過程分享給大家。 分析頁面,尋找切入點首先進入該平台的租房頁面,可以看到,主頁上的房源列表裡已經包括了我們所需要的大部分信息,並且這些資訊都能直接從dom中取得到,因此考慮直接透過模擬請求來收集網頁資料。https://sh.lianjia.com/zufang/因此接下來就要考慮怎麼取得url了。透過觀察我們發現,該地區一共有2w套以上的房源,而透過網頁只能訪問到前100頁的數據,每頁顯示數量上限是30條,算下來就是一共3k條,無法獲取到全部信息。 不過我們可以透過新增篩選條件來解決這個問題。在篩選項中選擇“靜安”,進入到如下的url:
https://sh.lianjia.com/zufang/jingan/#可以看到該地區一共有2k多套房來源,資料頁數為75,每頁30條,理論上可以存取到所有的資料。所以可以透過分別取得各區房源數據的方法,得到市府所有的數據。
https://sh.lianjia.com/zufang/jingan/pg2/點擊第二頁按鈕後,進入到了上面的url,可以發現只要修改pg後面的數字,就能進入到對應的頁數。 不過這裡發現一個問題,相同的頁數每次存取得到的資料是不一樣的,這樣會導致收集到的資料出現重複。所以我們點擊排序條件中的「最新上架",進入到如下連結:
https://sh.lianjia.com/zufang/jingan/pg2rco11/用這種排序方式獲得的資料順序是穩定的,至此我們的思路便有了:首先分別訪問每個小地區的第一頁,然後透過第一頁取得目前地區的最大頁數,然後存取模擬請求存取每一頁以取得所有資料。 爬取資料有了思路之後就要動手寫程式碼了,首先我們要收集包含所有的鏈接,程式碼如下:
# 所有小地区对应的标识 list=['jingan','xuhui','huangpu','changning','putuo','pudong','baoshan','hongkou','yangpu','minhang','jinshan','jiading','chongming','fengxian','songjiang','qingpu'] # 存放所有链接 urls = [] for a in list: urls.append('https://sh.lianjia.com/zufang/{}/pg1rco11/'.format(a)) # 设置请求头,避免ip被ban headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.9 Safari/537.36'} # 获取当前小地区第1页的dom信息 res = requests.get('https://sh.lianjia.com/zufang/{}/pg1rco11/'.format(a), headers=headers) content = res.text soup = BeautifulSoup(content, 'html.parser') # 获取当前页面的最大页数 page_num = int(soup.find('div', attrs={'class': 'content__pg'}).attrs['data-totalpage']) for i in range(2,page_num+1): # 将所有链接保存到urls中 urls.append('https://sh.lianjia.com/zufang/{}/pg{}rco11/'.format(a,i))之後,我們要逐一處理上一步得到的urls,取得連結內的數據,程式碼如下:
num=1 for url in urls: print("正在处理第{}页数据...".format(str(num))) res1 = requests.get(url, headers=headers) content1 = res1.text soup1 = BeautifulSoup(content1, 'html.parser') infos = soup1.find('div', {'class': 'content__list'}).find_all('div', {'class': 'content__list--item'})整理數據,匯出檔案透過對頁面結構的觀察,我們能得到每個元素儲存的位置,找到對應的頁面元素,就能取得到我們需要的資訊了。 這裡附上完整的程式碼,有興趣的朋友可以依照自己的需要,替換掉連結中的地區標識和小地區的標識,就能夠取得自己所在地區的資訊了。其他租屋平台的爬取方式大都類似,就不再贅述了。
import time, re, csv, requests import codecs from bs4 import BeautifulSoup print("****处理开始****") with open(r'..sh.csv', 'wb+')as fp: fp.write(codecs.BOM_UTF8) f = open(r'..sh.csv','w+',newline='', encoding='utf-8') writer = csv.writer(f) urls = [] # 所有小地区对应的标识 list=['jingan','xuhui','huangpu','changning','putuo','pudong','baoshan','hongkou','yangpu','minhang','jinshan','jiading','chongming','fengxian','songjiang','qingpu'] # 存放所有链接 urls = [] for a in list: urls.append('https://sh.lianjia.com/zufang/{}/pg1rco11/'.format(a)) # 设置请求头,避免ip被ban headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.9 Safari/537.36'} # 获取当前小地区第1页的dom信息 res = requests.get('https://sh.lianjia.com/zufang/{}/pg1rco11/'.format(a), headers=headers) content = res.text soup = BeautifulSoup(content, 'html.parser') # 获取当前页面的最大页数 page_num = int(soup.find('div', attrs={'class': 'content__pg'}).attrs['data-totalpage']) for i in range(2,page_num+1): # 将所有链接保存到urls中 urls.append('https://sh.lianjia.com/zufang/{}/pg{}rco11/'.format(a,i)) num=1 for url in urls: # 模拟请求 print("正在处理第{}页数据...".format(str(num))) res1 = requests.get(url, headers=headers) content1 = res1.text soup1 = BeautifulSoup(content1, 'html.parser') # 读取页面中数据 infos = soup1.find('div', {'class': 'content__list'}).find_all('div', {'class': 'content__list--item'}) # 数据处理 for info in infos: house_url = 'https://sh.lianjia.com' + info.a['href'] title = info.find('p', {'class': 'content__list--item--title'}).find('a').get_text().strip() group = title.split()[0][3:] price = info.find('span', {'class': 'content__list--item-price'}).get_text() tag = info.find('p', {'class': 'content__list--item--bottom oneline'}).get_text() mixed = info.find('p', {'class': 'content__list--item--des'}).get_text() mix = re.split(r'/', mixed) address = mix[0].strip() area = mix[1].strip() door_orientation = mix[2].strip() style = mix[-1].strip() region = re.split(r'-', address)[0] writer.writerow((house_url, title, group, price, area, address, door_orientation, style, tag, region)) time.sleep(0) print("第{}页数据处理完毕,共{}条数据。".format(str(num), len(infos))) num+=1 f.close() print("****全部完成****")經過一番操作,我們取得了當地各租屋平台完整的房源資訊。至此,我們已經可以透過一些基本的篩選方式,取得自己需要的數據了。
以上是為了在上海租房,我用Python連夜爬了20000多條房源資訊的詳細內容。更多資訊請關注PHP中文網其他相關文章!