那些年,我爬過的北科(九)——搜索案例之爬蟲編寫

案例介紹

從本章開始,咱們將要開始進入最後的案例實踐篇。html

在爬取數據以後,咱們通常會怎麼用數據呢?通常來說,咱們可能會作一個搜索引擎,好比說咱們爬了新聞,可能會作一個新聞的搜索;爬取了小說可能作一個小說的搜索。python

本案例將要爬取北科貼吧的帖子數據,並在此基礎上構建一個簡單的搜索功能。數據庫

百度貼吧分析

這裏咱們首先打開北京科技大學的百度貼吧:tieba.baidu.com/f?kw=北京科技大學app

咱們的目標是關注帖子的標題名稱,好比這個:「北郵人下載須要流量嗎」「請問一下學長學姐,全國大學生數學競賽初賽全國一等獎在我們學校」工具

還有就是咱們確定不能只爬取一頁的信息,這裏咱們將要爬取前1000頁的信息。網站

頁面分析

首先咱們打開Chrome開發者工具看一下列表如何解析。搜索引擎

這裏咱們選中一個標題名稱後,能夠直接看到一個a標籤,它的class爲j_th_titspa

因此使用如下代碼就能夠打印出全部的標題來。3d

soup = BeautifulSoup(resp.content, "html.parser")
items = soup.find_all("a", {"class", "j_th_tit"})
for a in items:
    title = item.get_text()
    print(title)
複製代碼

分頁分析

頁面分析完了以後就能夠分析一下分頁了,咱們把小箭頭晃到底部分頁的位置。code

能夠發現分頁對應的網址主要是pn的值不同。第2頁對應50,第3頁對應100,第4頁對應150。

也就是,$$pn=(page-1)*50$$這樣的關係。

爬蟲編寫

完成以上的分析工做以後,就能夠開始實現咱們的爬蟲了。

數據庫操做

首先是數據庫的操做,這裏使用到tieba數據庫的beike集合。而後保存文檔的話就直接insert就行了。

def init_collection():
    client = pymongo.MongoClient(host="localhost", port=27017)
    db = client['tieba']
    return db["beike"]


def save_docs(docs):
    beike.insert(docs)

beike = init_collection()
複製代碼

任務初始化

下面,咱們不編寫worker,而是先進行任務的初始化。

if __name__ == '__main__':
    crawler = SimpleCrawler(5)
    crawler.add_worker("worker", worker)
    for i in range(1, 11):
        crawler.add_task({"id": "worker", "page": i})
    crawler.start()
複製代碼

這裏咱們首先初始化SimpleCrawler,而後給添加worker以及task

關於task,能夠看到上面的代碼經過循環,添加了10個任務,每一個任務的page屬性不同。worker確定是爬取某一頁並解析加入數據庫的代碼,咱們這裏其實就是添加了爬取前10頁的任務。

這裏雖然也能夠寫直接添加爬取前1000頁的任務,可是考慮到實際狀況下任務可能會很是多,爲了讓任務隊列不溢出,開始能夠少添加一些。

Worker編寫

接下來是worker的編寫。

首先worker確定要有三個基礎部分:下載頁面、解析頁面、保存數據。除此以外,由於要爬取1000頁,因此還要添加新的任務來爬取剩下的990。

這裏能夠判斷當前頁碼+10是否大於1000,若是不大於的話把當前頁碼+10的網頁添加到新的任務隊列中。

def worker(queue, task, lock):
    offset = (task["page"] - 1) * 50
    print("downloading: page %d" % task["page"])
    # 1. 下載頁面
    resp = requests.get("http://tieba.baidu.com/f?kw="
                        "%E5%8C%97%E4%BA%AC%E7%A7%91%E6%8A%80%E5%A4%A7%E5%AD%A6&ie=utf-8&pn=" + str(offset))
    soup = BeautifulSoup(resp.content, "html.parser")

    # 2. 解析頁面
    items = soup.find_all("a", {"class", "j_th_tit"})

    docs = []
    for index, item in enumerate(items):
        docs.append({
            "page": task["page"],
            "index": index,
            "title": item.get_text(),
            "href": "http://tieba.baidu.com" + item.attrs["href"]
        })
        print(task["page"], index, item.get_text())
    # 3. 保存數據
    with lock:
        save_docs(docs)

    # 4. 添加新任務
    if (task["page"] + 10) > 1000:
        queue.put({"id": "NO"})
    else:
        queue.put({"id": "worker", "page": task["page"] + 10})
複製代碼

運行效果

以上就是爬蟲的所有代碼,運行後能夠看到類型下面的結果。

經過以上代碼大概爬了4萬多條數據,以後的兩章咱們將把這些標題當作語料庫,而後對這些數據進行搜索。

說明

網站可能會常常變化,若是上述爬蟲不能用的話,能夠爬取我保存下來的貼吧網頁:nladuo.cn/beike_tieba…

分頁的格式相似於1.html、2.html、...、1000.html。

相關文章
相關標籤/搜索