Python爬蟲學習-爬取大規模數據(10w級)

編譯環境:python v3.5.0, mac osx 10.11.4
<big>python爬蟲基礎知識: Python爬蟲學習-基礎爬取</big>

了解數據庫 MongoDB

  • 數據庫是儲存數據的地方,可以將如下的字典結構插入到MongoDB的存儲單元中。
    data = {
    'name':peter
    'id':123
    ...
    } # 需存儲的文件
  • 數據庫的構成:可以將其類比于excel表格進行理解
    client = pymongo.MongoClient('localhost',27017) # 將python與mongodb進行連接,'localhost'表示本地環境, 207017是端口號
    walden = client['walden'] # 創建一個庫文件
    以上代碼可以類似于創建一個excel文件,文件名為walden



    sheet_tab = walden['sheet_tab'] # 在庫文件中建立一個頁面名叫 sheet_tab
    以上代碼可以類似于創建excel文件中的一個表單


  • 數據庫的基本操作:
    1. 向頁邊中插入數據:sheet_tab.insert_one(data)
      其中data為python中的字典結構,可有如下代碼生成:
      path = './walden.txt' # 輸入數據的路徑,為讀取數據做準備
      with open(path,'r') as f: # 打開文件,為只讀模式
      lines = f.readlines()
      for index,line in enumerate(lines): # 逐個生成字典元素
      data = {
      'index':index,
      'line' :line,
      'words':len(line.split())
      }
      sheet_tab.insert_one(data) # 將字典元素插入庫文件頁面中
  1. 篩選數據庫中的數據(基礎篩選)
    sheet_tab.find({'words':{'$lt':5}} # 選擇字典中關鍵字words對應值小于5的所有字典元素
    # $lt/$lte/$gt/$gte/$ne,依次等價于</<=/>/>=/!=。(l表示less g表示greater e表示equal n表示not )

基礎實戰(篩選房源)

篩選小豬短租網站前三頁信息儲存到MongoDB中,篩選出價格大于等于500元房源,并打印出來。房源信息具體要求如下:

  • <big>實戰源碼</big> (下載地址xiaozhu.py
    # -- coding: utf-8 --
    import requests, time, pymongo
    from bs4 import BeautifulSoup
    def gender_info(soup): # 獲取性別信息
    gender = 'female' if soup.find_all('div','div.member_ico1') else 'male'
    return gender
    def get_info(url): # 獲取所需的房源信息
    wb_data = requests.get(url) # 向服務器請求頁面
    wb_data.encoding ='utf-8' # 標明編碼為utf-8,以免出現解碼錯誤
    soup = BeautifulSoup(wb_data.text,'lxml') # 以lxml方式對頁面進行解析
    title = soup.select('h4 em')[0].text
    address = soup.select('span.pr5')[0].text
    price = int(soup.select('div.day_l span')[0].text)
    img = soup.select('#curBigImage')[0].get('src')
    hostPic = soup.select('#floatRightBox > div.js_box.clearfix > div.member_pic > a > img')[0].get('src')
    hostName = soup.select('#floatRightBox > div.js_box.clearfix > div.w_240 > h6 > a')[0].text
    hostGender = gender_info(soup)
    data = {
    'title' : title,
    'address': address,
    'price' : price,
    'img' :img,
    'hostPic' : hostPic,
    'hostName' : hostName,
    'hostGender' : hostGender
    }
    print('get_info Done')
    return data
    def get_list_url(pageURL): # 獲取頁面中所有詳細房源的url
    listUrl = []
    wb_data = requests.get(pageURL)
    wb_data.encoding = 'utf-8'
    soup = BeautifulSoup(wb_data.text,'lxml')
    pageList = soup.select('div.result_btm_con.lodgeunitname')
    for i in pageList:
    listUrl.append(i.get('detailurl'))
    print('get_list_url Done')
    return listUrl
    def get_info_by_page(startPage, endPage, baseURL,database): # 獲取整個頁面的信息
    for i in range(startPage,endPage+1):
    url = baseURL.format(i)
    listUrl = get_list_url(url)
    for j in listUrl:
    time.sleep(4)
    dataInfo = get_info(j) # 獲取每個頁面的信息
    database.insert_one(dataInfo) # 將信息插入到指定的頁面中
    print('input to database Done')
    client = pymongo.MongoClient('localhost',27017) # 連接mongodb
    xiaozhu = client['xiaozhu'] # 創建一個名叫xiaozhu的庫文件
    home_info = xiaozhu['home_info'] # 創建一個home_info的頁面
    pageBaseUrl = 'http://bj.xiaozhu.com/search-duanzufang-p{}-0/' # 構造共同url連接
    get_info_by_page(1,3,pageBaseUrl,home_info) # 調用函數爬取信息并將信息儲存到mongodb中
    for info in home_info.find({'price':{'$gte':500}}): # 打印大于等于500的房源信息
    print(info)
  • <big>結果展示</big>
    mongoDB中的儲存結果(部分截圖)
    價格大于等于500的房源信息(部分截圖)

爬取工作分析流程

<big>1. </big>觀察頁面特征,保證爬蟲程序的通用性,即:發現邊界條件和局限性。
例:爬取趕集網-北京二手市場的所有類目中屬于<big>個人</big>的商品信息。

  • 觀察的到頁面(url)變動的信息


  • 發現頁面變動邊界條件
    1. 當把頁面設定到150頁時,我們發現返回的頁面是任意四件商品的信息。因此,我們要據此,判斷我們所爬取的頁面是否已經到頭。避免重復的信息加入到我們的數據庫中。
    2. 并且通過觀察發現網站這一返回操作,我們發現正常頁面中有列表鏈接可以點擊,而由于頁面超出范圍返回的隨機商品信息頁面沒有。
    3. 因此我們可以用BeautifulSoup庫中的find方法實現這個操作。
      soup.find('ul', 'pageLink') #找到返回TRUE,沒有返回FALSE
  • 一般這種交易網站,當商品賣出后,商品有關信息頁面將會被刪除,所以我們爬取的過程中,可能將有商品被賣出,當我們向服務器進行請求該商品詳情界面時會出現404 not found。我們可以通過status_code的方法對頁面進行判斷。
    wb_data.status_code == 404 # 判斷商品是否已被賣出,賣出則返回TRUE,沒有則返回FALSE

<big>2. </big>設計工作流程,保證輸出效率和穩定性。

  • 分步進行:先獲取channel_list(所有頻道分類的URL),保證爬取的穩定性。若是爬取類目信息,與爬取商品信息同步進行的話,當程序出現錯誤時,我們則什么信息也不能得到。所以分步進行可以降低風險。(圖中分類項目下的所有商品詳情鏈接)

  • 多進程爬取: 可以利用multiprocess庫中的pool函數,進行多進程爬取,這樣可以提高爬取的效率。
    關于進程與線程:
    可以理解成多個人完成吃飯這個工作的效率:
    單線程單進程:只有一個餐桌,一個人在一個餐桌上吃飯,每個人依次進行。
    單線程多進程:有多個餐桌,每個餐座上只有一個人在吃飯。
    單進程多線程: 只有一個餐桌,一個餐桌上可以坐多個人。
    多進程多線程:多個餐座,一個餐桌上可以坐多個人。

  • 對項目進行監測:
    我們可以設計一個檢測函數,隔一段時間匯報所抓取信息的數量,對項目進程進行掌控。
    import timeframe page_parsing
    import url_list
    while True:
    print(url_list.find().count())
    time.sleep(5)

  • 設計斷點續傳程序:
    由于在我們抓取的過程中可能會遇到網絡問題,導致程序終止,而我們不希望重新開始抓取,而是在中斷后的地方繼續進行抓取。

    設計思路如下:

    1. 數據庫中建立兩個頁面存放詳情商品鏈接(從這一點也可以看出分步抓取的重要性)。一個存放需要抓取的(url_list1)一個存放已經抓取網商品信息的 (url_list2)。
  1. 當中斷后繼續抓取時,url_list1-url_list2就是剩下帶抓取的商品信息頁面。
    db_urls = [item['url'] for item in url_list.find()] # 用列表解析式裝入所有要爬取的鏈接
    index_urls = [item['url'] for item in item_info.find()] # 所引出詳情信息數據庫中所有的現存的 url 字段
    x = set(db_urls) # 轉換成集合的數據結構
    y = set(index_urls)rest_of_urls = x-y # 剩下的url

爬取結果以及源碼(按設計步驟展示)

**All source code **: JacobKam-GitHub

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,327評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,996評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,316評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,406評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,128評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,524評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,576評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,759評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,310評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,065評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,249評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,821評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,479評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,909評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,140評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,984評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,228評論 2 375

推薦閱讀更多精彩內容