1. 程式人生 > >python爬蟲(3)——python爬取大規模資料的的方法和步驟

python爬蟲(3)——python爬取大規模資料的的方法和步驟

python爬取大規模資料的的方法和步驟:

一、爬取我們所需要的一線連結

channel_extract.py
這裡的一線連結也就是我們所說的大類連結:

from bs4 import BeautifulSoup
import requests

start_url = 'http://lz.ganji.com/wu/'
host_url = 'http://lz.ganji.com/'

def get_channel_urls(url):
    wb_data = requests.get(url)
    soup = BeautifulSoup(wb_data.text, 'lxml'
) links = soup.select('.fenlei > dt > a') #print(links) for link in links: page_url = host_url + link.get('href') print(page_url) #get_channel_urls(start_url) channel_urls = ''' http://lz.ganji.com/jiaju/ http://lz.ganji.com/rirongbaihuo/ http://lz.ganji.com/shouji/ http://lz.ganji.com/bangong/ http://lz.ganji.com/nongyongpin/ http://lz.ganji.com/jiadian/ http://lz.ganji.com/ershoubijibendiannao/ http://lz.ganji.com/ruanjiantushu/ http://lz.ganji.com/yingyouyunfu/ http://lz.ganji.com/diannao/ http://lz.ganji.com/xianzhilipin/ http://lz.ganji.com/fushixiaobaxuemao/ http://lz.ganji.com/meironghuazhuang/ http://lz.ganji.com/shuma/ http://lz.ganji.com/laonianyongpin/ http://lz.ganji.com/xuniwupin/ '''

那麼拿我爬取的58同城為例就是爬取了二手市場所有品類的連結,也就是我說的大類連結;
找到這些連結的共同特徵,用函式將其輸出,並作為多行文字儲存起來。

二、獲取我們所需要的詳情頁面的連結和詳情資訊

page_parsing.py

1、說說我們的資料庫:

先看程式碼:

#引入庫檔案
from bs4 import BeautifulSoup
import requests
import pymongo #python操作MongoDB的庫
import re
import time

#連結和建立資料庫
client = pymongo.MongoClient('localhost'
, 27017) ceshi = client['ceshi'] #建ceshi資料庫 ganji_url_list = ceshi['ganji_url_list'] #建立表文件 ganji_url_info = ceshi['ganji_url_info']

2、判斷頁面結構是否和我們想要的頁面結構相匹配,比如有時候會有404頁面;

3、從頁面中提取我們想要的連結,也就是每個詳情頁面的連結;

這裡我們要說的是一個方法就是:
item_link = link.get('href').split('?')[0]

這裡的這個link什麼型別的,這個get方法又是什麼鬼?
後來我發現了這個型別是

<class 'bs4.element.Tab>

如果我們想要單獨獲取某個屬性,可以這樣,例如我們獲取它的 class 叫什麼

print soup.p['class']
#['title']

還可以這樣,利用get方法,傳入屬性的名稱,二者是等價的

print soup.p.get('class')
#['title']

下面我來貼上程式碼:

#爬取所有商品的詳情頁面連結:
def get_type_links(channel, num):
    list_view = '{0}o{1}/'.format(channel, str(num))
    #print(list_view)
    wb_data = requests.get(list_view)
    soup = BeautifulSoup(wb_data.text, 'lxml')
    linkOn = soup.select('.pageBox') #判斷是否為我們所需頁面的標誌;
    #如果爬下來的select連結為這樣:div.pageBox > ul > li:nth-child(1) > a > span  這裡的:nth-child(1)要刪掉
    #print(linkOn)
    if linkOn:
        link = soup.select('.zz > .zz-til > a')
        link_2 = soup.select('.js-item > a')
        link = link + link_2
        #print(len(link))
        for linkc in link:
            linkc = linkc.get('href')
            ganji_url_list.insert_one({'url': linkc})
            print(linkc)
    else:
        pass

4、爬取詳情頁中我們所需要的資訊

我來貼一段程式碼:

#爬取趕集網詳情頁連結:
def get_url_info_ganji(url):
    time.sleep(1)
    wb_data = requests.get(url)
    soup = BeautifulSoup(wb_data.text, 'lxml')
    try:
        title = soup.select('head > title')[0].text
        timec = soup.select('.pr-5')[0].text.strip()
        type = soup.select('.det-infor > li > span > a')[0].text
        price = soup.select('.det-infor > li > i')[0].text
        place = soup.select('.det-infor > li > a')[1:]
        placeb = []
        for placec in place:
            placeb.append(placec.text)
        tag = soup.select('.second-dt-bewrite > ul > li')[0].text
        tag = ''.join(tag.split())
        #print(time.split())
        data = {
            'url' : url,
            'title' : title,
            'time' : timec.split(),
            'type' : type,
            'price' : price,
            'place' : placeb,
            'new' : tag
        }
        ganji_url_info.insert_one(data) #向資料庫中插入一條資料;
        print(data)
    except IndexError:
        pass

四、我們的主函式怎麼寫?

main.py
看程式碼:

#先從別的檔案中引入函式和資料:
from multiprocessing import Pool
from page_parsing import get_type_links,get_url_info_ganji,ganji_url_list
from channel_extract import channel_urls

#爬取所有連結的函式:
def get_all_links_from(channel):
    for i in range(1,100):
        get_type_links(channel,i)

#後執行這個函式用來爬取所有詳情頁的檔案:
if __name__ == '__main__':
#     pool = Pool()
#     # pool = Pool()
#     pool.map(get_url_info_ganji, [url['url'] for url in ganji_url_list.find()])
#     pool.close()
#     pool.join()


#先執行下面的這個函式,用來爬取所有的連結:
if __name__ == '__main__':
    pool = Pool()
    pool = Pool()
    pool.map(get_all_links_from,channel_urls.split())
    pool.close()
    pool.join()

五、計數程式

count.py
用來顯示爬取資料的數目;

import time
from page_parsing import ganji_url_list,ganji_url_info
while True:
    # print(ganji_url_list.find().count())
    # time.sleep(5)
    print(ganji_url_info.find().count())
    time.sleep(5)