python爬蟲--爬取鏈家租房資訊

愛學習的番茄醬發表於2020-05-16

python 爬蟲-鏈家租房資訊

爬蟲,其實就是爬取web頁面上的資訊。

鏈家租房資訊頁面如下:
https://gz.lianjia.com/zufang/

在這裡插入圖片描述
在這裡插入圖片描述## python庫

Python庫

1.request 用來獲取頁面內容
2.BeatifulSoup

request文件連結:
https://requests.readthedocs.io/zh_CN/latest/user/quickstart.html
BeatifulSoup文件連結:
https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html

先安裝這兩個包

安裝requests和BeautifulSoup:

跟上篇同樣的方法,安裝成功的介面如下:
安裝程式碼:

pip install requests

在這裡插入圖片描述程式碼:pip install bs4
在這裡插入圖片描述
同樣檢查一下:
在這裡插入圖片描述代表安裝成功了。

遇到問題:python還是無法識別requests庫。百度了一下。解決辦法如下:
開啟Python檔案的安裝目錄,進入Scripts檔案中,按住Shift鍵+滑鼠右擊,選擇【在此處開啟Powershell視窗】
在這裡插入圖片描述可以看到,requests的確存在了。
此時進入python,點選file-settigngs,選擇【Project Interpreter】,在右邊的列表裡可以看到已經安裝的各種庫、對應的版本以及最新版本,然後點選 + 號,搜尋報錯的那個庫,比如本文的 requests 庫,選中後點選【Install Package】安裝庫,安裝成功後右下角會有提示 Packages installed successfully,再次執行程式就沒有報錯了!
同理下載bs4。
執行結果:
在這裡插入圖片描述
原博:
https://blog.csdn.net/qq_36759224/article/details/100026277

import requests
from bs4 import BeautifulSoup
url = "https://gz.lianjia.com/zufang/"
responce = requests.get(url)
soup = BeautifulSoup(responce.text,'lxml')
# print(responce.text)
print(soup)

執行時報錯:
bs4.FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml. Do you need to install a parser library?
解決:原因是沒有下載lxml需要的東西,下載一個就好了。
在這裡插入圖片描述下載完之後,from bs4 import BeautifulSoup是不報錯了,但是執行之後還是報錯,把lxml改為html.parser,執行結果沒有問題!

import requests
from bs4 import BeautifulSoup
url = "https://gz.lianjia.com/zufang/"
responce = requests.get(url)
soup = BeautifulSoup(responce.text,'html.parser')
# print(responce.text)
print(soup)

原博:
https://blog.csdn.net/weixin_44024857/article/details/87904685

開啟網頁,右鍵,檢查,看到這行顏色變了,找到div class的名字是content__list–item–main。
在這裡插入圖片描述
程式碼這麼寫:

links_div = soup.find_all('div', class_="content__list--item--main")
# links = [for div in links_div]
print(links_div)   #裡面存了一個列表
# print(links_div[0])   #檢視第一個
# print(links)

執行結果:
在這裡插入圖片描述檢視列表其中一個元素,這裡檢視第一個:
在這裡插入圖片描述
但是我們只想要連結,不要圖片等其他的資訊,也就是a href後面的連結,程式碼如下:

links_div = soup.find_all('div', class_="content__list--item--main")
links = [div.a.get('href') for div in links_div]
# print(links_div)   #裡面存了一個列表
# print(links_div[0].a.get('href'))   #檢視第一個
print(links,len(links))

此時,我們就獲取到了當前頁面的全部連結,長度為33。

在這裡插入圖片描述

封裝成函式,作用是獲取列表頁下面的所有租房頁面的連結,返回一個連結列表

def get_links(url):
    responce = requests.get(url)
    soup = BeautifulSoup(responce.text, 'html.parser')
    links_div = soup.find_all('div', class_="content__list--item--main")
    links = [div.a.get('href') for div in links_div]
    return links

url = "https://gz.lianjia.com/zufang/"
print(get_links(url))
結果相同:
['/zufang/GZ2298305088701612032.html', '/zufang/GZ2381801160471756800.html', '/zufang/GZ2359884100317757440.html', '/apartment/7268.html', '/zufang/GZ2499974203789549568.html', '/apartment/19264.html', '/zufang/GZ2499100907166777344.html', '/zufang/GZ2499209752543248384.html', '/zufang/GZ2497822820261183488.html', '/zufang/GZ2497607240542846976.html', '/zufang/GZ2498431143112876032.html', '/zufang/GZ2310049470823809024.html', '/zufang/GZ2499346361594953728.html', '/zufang/GZ2392521977211928576.html', '/zufang/GZ2499056259253411840.html', '/zufang/GZ2500010005773172736.html', '/zufang/GZ2500031132138217472.html', '/zufang/GZ2499288504467996672.html', '/zufang/GZ2499020325493145600.html', '/zufang/GZ2499120229419065344.html', '/zufang/GZ2499377558819717120.html', '/zufang/GZ2378856616616534016.html', '/zufang/GZ2497621306694959104.html', '/zufang/GZ2330296981744271360.html', '/zufang/GZ2497812365010010112.html', '/zufang/GZ2354164126701592576.html', '/zufang/GZ2497645065968041984.html', '/zufang/GZ2334517367570710528.html', '/zufang/GZ2321645290765434880.html', '/zufang/GZ2362854688652525568.html', '/zufang/GZ2344044030008238080.html', '/zufang/GZ2325288593729257472.html', '/zufang/GZ2354875364645543936.html']

點進其中一個頁面,https://gz.lianjia.com/zufang/GZ2298305088701612032.html?nav=0&unique_id=dd85aae4-ba2d-46af-a027-1b5a920a1b70zufang1589621537856,檢查元素,點選圖片左上角的箭頭,這樣我們點到頁面哪個地方,都會相對應定為到檢視器哪個地方。比如點到租金2000元,定位到了<span>那一行,沒有class,怎麼辦呢?試著把class寫成上一行的content__aside–title,結果可以爬到,可是多了一些,用字串擷取一下。
在這裡插入圖片描述
在這裡插入圖片描述接下來一點點提取面積、樓層等資訊。
在這裡插入圖片描述

租金

點到租金2000元,定位到了<span>那一行,沒有class,怎麼辦呢?試著把class寫成上一行的content__aside–title,結果可以爬到,可是多了一些,用字串擷取一下。

# 獲取url下的頁面內容,返回soup物件
def get_page(url):
    responce = requests.get(url)
    soup = BeautifulSoup(responce.text, 'html.parser')
    return soup

# 封裝成函式,作用是獲取列表頁下面的所有租房頁面的連結,返回一個連結列表
def get_links(link_url):
    soup = get_page(link_url)
    links_div = soup.find_all('div', class_="content__list--item--main")
    links = [div.a.get('href') for div in links_div]
    return links

house_url = 'https://gz.lianjia.com/zufang/GZ2298305088701612032.html?nav=0&unique_id=' \
            'dd85aae4-ba2d-46af-a027-1b5a920a1b70zufang1589621537856'
soup = get_page(house_url)
# print(soup.find('div', class_='content__aside--title').text)
price = soup.find('div', class_='content__aside--title').text
print(price[1:8])

.text可以列印出我們真正想要獲取的文字。執行結果:
在這裡插入圖片描述
最後把這個結果賦值給price。擷取後剛好爬到租金!
在這裡插入圖片描述

因為這裡的單位已經跟價格一起顯示了,所以不用單獨再寫程式碼爬了。如果要寫的話,跟價格時一樣的,比如

# unit = soup.find('span', class_='total').text
# unit.strip()

合併:

unit = soup.find('span', class_='total').text.strip()

意思是一樣的。strip函式可以把兩邊的空格刪除。

面積:

點選面積,定位到下圖的地方,是一個列表的樣式,這時我們find_all就好了。
在這裡插入圖片描述程式碼如下:

house_info = soup.find_all('li',class_='fl oneline')
print(house_info)

列印house_info看一下:
在這裡插入圖片描述所有的租房資訊都出現了。
但我們只要文字,列印住房面積看一下:

print(house_info[1].text)

結果:
在這裡插入圖片描述
但是“面積:”這三個字元我們是不需要的,擷取掉:

print(house_info[1].text[3:])

結果:
在這裡插入圖片描述把面積賦給area

area = house_info[1].text[3:]

朝向

第二個資訊是朝向,同樣的程式碼:

chaoxiang = house_info[2].text[3:]

結果:

在這裡插入圖片描述沒有問題!

維護

第三個是維護。

入住

同上。

chaoxiang = house_info[2].text[3:]
weihu = house_info[4].text[3:]
ruzhu = house_info[5].text[3:]
louceng = house_info[7].text[3:]
dianti = house_info[8].text[3:]
print(chaoxiang, weihu, ruzhu, louceng)

暫時爬這幾個。
在這裡插入圖片描述

租賃方式

自己試著爬了租賃方式這塊的資訊,定位到檢查元素,同樣是find_all
在這裡插入圖片描述在這裡插入圖片描述如果把class成label,只要爬到下圖:
在這裡插入圖片描述試了一下把class寫成content__aside__list,也就是藍色的地方。

lease = soup.find_all('ul', class_='content__aside__list')
# lease = soup.find_all('span', class_='label')
print(lease)

在這裡插入圖片描述這樣才能爬到完整的資訊。

在後面加上text想只保留文字
注意!不能直接lease.text,因為lease是find_all出來的一個列表,不是find函式,如果是price就可以直接在後面加 .text

price = soup.find('div', class_='content__aside--title').text

但是find_all不行,要先指定其中一個元素:

lease = soup.find_all('ul', class_='content__aside__list')
# lease = soup.find_all('span', class_='label')
print(lease[0].text)

這樣文字就出來了:
在這裡插入圖片描述同樣的,"租賃方式:"這五個字元不需要,擷取掉:

print(lease[0].text[6:])

這樣列印出來的就是整租兩個字了。
這裡因為lease[0]就是全部文字,所以一個個擷取出來。

print(lease[0].text[6:9],lease[0].text[14:25],lease[0].text[30:40])

結果:
在這裡插入圖片描述把所有資訊列印看一下:

info = {
    '價格':price,
    '面積':area,
    '朝向':chaoxiang,
    '維護':weihu,
    '入住':ruzhu,
    '樓層':louceng,
    '電梯':dianti,
    '租賃資訊':lease_info
}
print(info)

結果:

{'價格': '2000元/月', '面積': '73㎡', '朝向': '東北', '維護': '今天', '入住': '隨時入住', '樓層': '高樓層/6層', '電梯': '無', '租賃資訊': ('整租\n', '2室1廳1衛 73㎡\n', '東北 高樓層/6層\n')}

對房屋資訊進行封裝

1.先在navicat把表格建好

在這裡插入圖片描述

2.把連線資料庫函式也封裝一下

DATABASE = {                   #一個資料庫,寫成字典;如果是多個資料庫連線,寫成列表[{配置資訊},{}]
    'host':'localhost',    #localhost相當於127.0.0.1,如果是遠端資料庫,此處為遠端伺服器的ip地址
    'database':'lj',
    'user':'root',
    'password':'1234'
}
def get_db(setting):
    return pymysql.connect(**setting)

def insert(db, house):
    values = "'{}',"*7 +"'{}'"
    sql_values = values.format(house['價格'],house['面積'],house['朝向'],house['維護'],
                               house['入住'],house['樓層'],house['電梯'],house['租賃資訊'])
    sql = """
    insert into house(price,area,chaoxiang,weihu,ruzhu,louceng,dianti,lease_info)
     values({});
    """.format(sql_values)
    print(sql)
    cursor = db.cursor()
    cursor.execute(sql)
    db.commit()

3.插入資料庫

house = get_house_info('https://gz.lianjia.com/zufang/GZ2298305088701612032.html?'
                       'nav=0&unique_id=dd85aae4-ba2d-46af-a027-1b5a920a1b70zufang1589621508886')
# print(house)
db = get_db(DATABASE)
insert(db,house)

因為租賃資訊是個元組,插入資料庫總是報錯,我改成了text,把沒有擷取的整段文字傳進去了。如圖:插入資料庫成功

4.爬取多條資訊

db = get_db(DATABASE)
links = get_links('https://gz.lianjia.com/zufang/')
for link in links:
    time.sleep(2)
    print("獲取一個房子資訊成功")
    house = get_house_info(link)
    # print(house, end='\r')
    insert(db,house)

最後爬取成功
在這裡插入圖片描述
原始碼:
https://github.com/CSU-liujie/wanmen/blob/master/%E7%88%AC%E8%99%AB-%E9%93%BE%E5%AE%B6%E7%A7%9F%E6%88%BF%E4%BF%A1%E6%81%AF

相關文章