1. 程式人生 > >爬取鏈家網租房資訊(萬級資料的簡單實現)

爬取鏈家網租房資訊(萬級資料的簡單實現)

這不是一個很難的專案,沒有ajax請求,也沒有用框架,只是一個requests請求和BeautifulSoup的解析

不過,看這段程式碼你會發現,BeautifulSoup不止只有find和fing_all用於元素定位,還有fing_next等其他的更簡單的,你如果某事覺得xpath比BeautifulSoup更簡單,那你真的應該結合我這個再把BeautifulSoup文件再看一遍,你會發現基於lxml解析的BeautifulSoup更強大

當然程式碼中還有一些小的細節,可以讓你學到一些東西。比如,物件的傳入,如何避免頻繁的IO操作

那接下來就貼程式碼了,程式碼中有註釋,沒有什麼好解釋的,所以接下來就只剩下程式碼和程式碼的註釋了! 如果有不懂得可以私信。

# _*_ coding:utf-8 _*_

import time,csv
from random import uniform,choice
import requests
from bs4 import BeautifulSoup





cities = ['bj', 'sh', 'nj', 'wh', 'cd', 'xa','hf']
# 一個我們將要爬取城市的列表

def get_city():
    global cities
    try:
        city = choice(cities)
        cities.remove(city)
        # 隨機選取一個城市進行爬取,然後再列表中刪除這個城市
print(cities) except IndexError: return None # 當沒有城市了,就返回一個None return city def get_url(index,city): if city == None: return # 城市值為None時,我們就跳出 else: if index == 1: url = 'https://{city}.lianjia.com/zufang/'.format(city=city) return
url # 這是首頁連結 else: url = 'https://{city}.lianjia.com/zufang/pg{index}'.format(index=index,city=city) return url def get_ressponse(url,file,headers): html = requests.get(url=url,headers=headers,verify=False) Soup = BeautifulSoup(html.text,'lxml') house_list = Soup.find(attrs={'id':'house-lst'}).find_all('li') for li in house_list: detail_mes = li.a['href'] img_house = li.img['src'] title = li.h2.a.get_text(strip=True) region = li.find_next(attrs={'class':'where'}).a.get_text(strip=True) zone = li.find_next(attrs={'class':'zone'}).span.get_text(strip=True) meters = li.find_next(attrs={'class':'meters'}).get_text(strip=True) directory = li.find_next(attrs={'class':'meters'}).find_next_sibling('span').get_text() other = li.find_next(attrs={'class':'other'}).find('div').get_text(strip=True) chanquan = li.find_next(attrs={'class':'chanquan'}).get_text(strip=True) file.writerow([detail_mes,img_house,title,region,zone,meters,directory,other,chanquan]) # 我們將傳進一個csv的寫的物件,對檔案進行寫操作 def main(city): for index in range(1, 101): try: if index == 1 or index == 2: headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Referer': 'https://{city}.lianjia.com/zufang/pg3'.format(city=city), # 我們動態的調換跳轉的頁面,覺得更像人的點選行為 'Host': '{city}.lianjia.com'.format(city=city), # 這裡我們動態的調換要訪問的主機 } else: headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Referer': 'https://{city}.lianjia.com/zufang/pg3'.format(city=city,index=index-1), 'Host': '{city}.lianjia.com'.format(city=city), } # 注意這裡的請求頭我們在不同的情況下值是不一樣的 # 當然請求頭你不換也許並不會導致出錯,但是這也是一種反爬蟲的方法,學習一下? url = get_url(index,city) get_ressponse(url=url, file=writer,headers=headers) # 將請求頭傳入 # 傳進連結和寫物件 t = uniform(1, 3) time.sleep(t) # 強制要求請求休息一下,我們這裡用1,3之間的隨機數 except AttributeError: print('我發現了一個錯誤') except UnicodeEncodeError: print('有一個編碼錯誤') # 兩個錯誤檢查 if __name__ == '__main__': with open('D:/scrapy的message/lianjia.csv','a',encoding='utf-8') as f: # 因為預設的讀寫操作是gbk,所以最好還是改成utf-8 # 在這裡開啟檔案而不是在迴圈中開啟,我們就可以避免頻繁的IO操作 writer = csv.writer(f) # 建立一個寫物件 writer.writerow(['detail_mes','img_house','title','region','zone,meters','directory','other','chanquan']) # 寫入表頭 for x in range(0,100): city = get_city() time.sleep(10) # 城市間的跳轉等待時間稍微長一點,畢竟我們要更友好對不對! print('正在爬取的城市是:%s' % city) if city == None: break # 如果沒有城市了,那就跳出迴圈停止了。 main(city)

按照慣例,我應該貼一下我的成果:
這裡寫圖片描述
可以看到一共6千多資料除以2,哈哈哈哈哈哈哈!!!!!
改進之後就可以實現萬級資料的爬取了,當然我並沒有然他執行完成,還會更多哦
這裡寫圖片描述