Python爬蟲入門教程 34-100 掘金網全站用戶爬蟲 scrapy

来源:https://www.cnblogs.com/happymeng/archive/2019/02/15/10381549.html
-Advertisement-
Play Games

爬前叨叨 已經編寫了33篇爬蟲文章了,如果你按著一個個的實現,你的爬蟲技術已經入門,從今天開始慢慢的就要寫一些有分析價值的數據了,今天我選了一個《掘金網》,我們去爬取一下他的 全站用戶 數據。 爬取思路 獲取全站用戶,理論來說從1個用戶作為切入點就可以,我們需要爬取用戶的關註列表,從關註列表不斷的疊 ...


爬前叨叨

已經編寫了33篇爬蟲文章了,如果你按著一個個的實現,你的爬蟲技術已經入門,從今天開始慢慢的就要寫一些有分析價值的數據了,今天我選了一個《掘金網》,我們去爬取一下他的全站用戶數據。

爬取思路

獲取全站用戶,理論來說從1個用戶作為切入點就可以,我們需要爬取用戶的關註列表,從關註列表不斷的疊加下去。

隨便打開一個用戶的個人中心

在這裡插入圖片描述

綠色圓圈裡面的都是我們想要採集到的信息。這個用戶關註0人?那麼你還需要繼續找一個入口,這個用戶一定要關註了別人。選擇關註列表,是為了讓數據有價值,因為關註者裡面可能大量的小號或者不活躍的賬號,價值不大。

我選了這樣一個入口頁面,它關註了3個人,你也可以選擇多一些的,這個沒有太大影響!
https://juejin.im/user/55fa7cd460b2e36621f07dde/following
我們要通過這個頁面,去抓取用戶的ID
在這裡插入圖片描述

得到ID之後,你才可以拼接出來下麵的鏈接

https://juejin.im/user/用戶ID/following

爬蟲編寫

分析好了之後,就可以創建一個scrapy項目了

items.py 文件,用來限定我們需要的所有數據,註意到下麵有個_id = scrapy.Field() 這個先預留好,是為了mongdb準備的,其他的欄位解釋請參照註釋即可。

class JuejinItem(scrapy.Item):
   
    _id = scrapy.Field()
    username = scrapy.Field()
    job = scrapy.Field()
    company =scrapy.Field()
    intro = scrapy.Field()
    # 專欄
    columns = scrapy.Field()
    # 沸點
    boiling = scrapy.Field()
    # 分享
    shares = scrapy.Field()
    # 贊
    praises = scrapy.Field()
    #
    books = scrapy.Field()
    # 關註了
    follow = scrapy.Field()
    # 關註者
    followers = scrapy.Field()
    goods = scrapy.Field()
    editer = scrapy.Field()
    reads = scrapy.Field()
    collections = scrapy.Field()
    tags = scrapy.Field()

編寫爬蟲主入口文件 JuejinspiderSpider.py

import scrapy
from scrapy.selector import Selector
from Juejin.items import JuejinItem

class JuejinspiderSpider(scrapy.Spider):
    name = 'JuejinSpider'
    allowed_domains = ['juejin.im']
    # 起始URL    5c0f372b5188255301746103
    start_urls = ['https://juejin.im/user/55fa7cd460b2e36621f07dde/following']

def parse 函數,邏輯不複雜,處理兩個業務即可

  1. 返回item
  2. 返回關註列表的Request

item的獲取,我們需要使用xpath匹配即可,為了簡化代碼量,我編寫了一個提取方法,叫做get_default函數。

    def get_default(self,exts):
        if len(exts)>0:
            ret = exts[0]
        else:
            ret = 0
        return ret

    def parse(self, response):
        #base_data = response.body_as_unicode()
        select = Selector(response)
        item = JuejinItem()
        # 這個地方獲取一下數據
        item["username"] = select.xpath("//h1[@class='username']/text()").extract()[0]
        position = select.xpath("//div[@class='position']/span/span/text()").extract()
        if position:
            job = position[0]
            if len(position)>1:
                company = position[1]
            else:
                company = ""
        else:
            job = company = ""
        item["job"] = job
        item["company"] = company
        item["intro"] = self.get_default(select.xpath("//div[@class='intro']/span/text()").extract())
        # 專欄
        item["columns"] = self.get_default(select.xpath("//div[@class='header-content']/a[2]/div[2]/text()").extract())
        # 沸點
        item["boiling"] = self.get_default(select.xpath("//div[@class='header-content']/a[3]/div[2]/text()").extract())
        # 分享
        item["shares"] = self.get_default(select.xpath("//div[@class='header-content']/a[4]/div[2]/text()").extract())
        # 贊
        item["praises"] = self.get_default(select.xpath("//div[@class='header-content']/a[5]/div[2]/text()").extract())
        #
        item["books"] = self.get_default(select.xpath("//div[@class='header-content']/a[6]/div[2]/text()").extract())

        # 關註了
        item["follow"] = self.get_default(select.xpath("//div[@class='follow-block block shadow']/a[1]/div[2]/text()").extract())
        # 關註者
        item["followers"] = self.get_default(select.xpath("//div[@class='follow-block block shadow']/a[2]/div[2]/text()").extract())


        right = select.xpath("//div[@class='stat-block block shadow']/div[2]/div").extract()
        if len(right) == 3:
            item["editer"] = self.get_default(select.xpath("//div[@class='stat-block block shadow']/div[2]/div[1]/span/text()").extract())
            item["goods"] = self.get_default(select.xpath("//div[@class='stat-block block shadow']/div[2]/div[2]/span/span/text()").extract())
            item["reads"] = self.get_default(select.xpath("//div[@class='stat-block block shadow']/div[2]/div[3]/span/span/text()").extract())

        else:
            item["editer"] = ""
            item["goods"] = self.get_default(select.xpath("//div[@class='stat-block block shadow']/div[2]/div[1]/span/span/text()").extract())
            item["reads"] = self.get_default(select.xpath("//div[@class='stat-block block shadow']/div[2]/div[2]/span/span/text()").extract())


        item["collections"] = self.get_default(select.xpath("//div[@class='more-block block']/a[1]/div[2]/text()").extract())
        item["tags"] = self.get_default(select.xpath("//div[@class='more-block block']/a[2]/div[2]/text()").extract())
        yield item  # 返回item
 

上述代碼,已經成功返回了item,打開setting.py文件中的pipelines設置,測試一下是否可以存儲數據,順便在
DEFAULT_REQUEST_HEADERS 配置一下request的請求參數。

setting.py

DEFAULT_REQUEST_HEADERS = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language': 'en',
    "Host": "juejin.im",
    "Referer": "https://juejin.im/timeline?sort=weeklyHottest",
    "Upgrade-Insecure-Requests": "1",
    "User-Agent": "Mozilla/5.0 瀏覽器UA"
}

ITEM_PIPELINES = {
   'Juejin.pipelines.JuejinPipeline': 20,
}

本爬蟲數據存儲到mongodb裡面,所以需要你在pipelines.py文件編寫存儲代碼。


import time
import pymongo

DATABASE_IP = '127.0.0.1'
DATABASE_PORT = 27017
DATABASE_NAME = 'sun'
client = pymongo.MongoClient(DATABASE_IP,DATABASE_PORT)
db = client.sun
db.authenticate("dba", "dba")
collection = db.jujin  # 準備插入數據


class JuejinPipeline(object):

    def process_item(self, item, spider):
        try:
            collection.insert(item)
        except Exception as e:
            print(e.args)

運行代碼之後,如果沒有報錯,完善最後一步即可,在Spider裡面將爬蟲的迴圈操作完成

      list_li = select.xpath("//ul[@class='tag-list']/li")  # 獲取所有的關註
      for li in list_li:
           a_link = li.xpath(".//meta[@itemprop='url']/@content").extract()[0] # 獲取URL
             # 返回拼接好的數據請求
           yield scrapy.Request(a_link+"/following",callback=self.parse)

所有的代碼都已經寫完啦
在這裡插入圖片描述

全站用戶爬蟲編寫完畢,厲害吧。

擴展方向

  1. 爬蟲每次只爬取關註列表的第一頁,也可以迴圈下去,這個不麻煩
  2. setting.py中開啟多線程操作
  3. 添加redis速度更快,後面會陸續的寫幾篇分散式爬蟲,提高爬取速度
  4. 思路可以擴展,N多網站的用戶爬蟲,咱後面也寫幾個

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在寫移動端導航的時候經常用到點擊按鈕出現/隱藏導航條的情況,最常見的方法當然還是前端框架直接調用,省心省力,不易出錯;當然還有使用純JS實現的小代碼段。我這裡整理了純CSS實現方式,給需要的人和給自己做個筆記: 實現原理利用CSS偽類:target 可以配合CSS3過渡做出很多不同的效果,具體不做詳 ...
  • echo.js的github地址:https://github.com/toddmotto/echo echo是一個獨立的JavaScript、輕量級的、延遲圖片載入插件,echo壓縮後體積不到1k,使用html的標準data-*屬性,echo支持IE8+。 一般將其放在滾動事件的下麵: <img ...
  • 1. 通過 id 查找 HTML 元素 2. 通過標簽名查找 HTML 元素 ...
  • 在 CSS3 之前,web 設計師必須使用已在用戶電腦上安裝好的字體。 通過 CSS3,web 設計師可以使用他們喜歡的任意字體。 當您找到或購買到希望使用的字體時,可將該字體文件存放到 web 伺服器上,它會在需要時被自動下載到用戶的電腦上。 您“自己的”的字體是在 CSS3 @font-fa ...
  • 簡介: 單例模式是一種簡單的設計模式,但是要在程式設計中使用好單例模式,卻需要註意幾個地方。 單例模式意味著在整個系統中,單例類只能有一個實例對象,且需要自行完成實例化,並始終對外提供同一個實例對象。 單例模式實現方式: 餓漢模式: 懶漢模式(單線程版): 上述懶漢模式有延遲載入的意思,但是沒有考慮 ...
  • 1、兩種創建方式 使用字面量創建時只會生成一個對象,而通過構造方法創建時會生成兩個對象(前面的str2和後面的new String對象) 2、常見的構造方法 3、其它常用方法 4、String、StringBuffer、StringBuilder 4.1、String是不可變的字元序列,在定義時長度 ...
  • 【New責任鏈&裝飾者】 感慨一下,本以為上下篇能一起發呢,結果要隔一定時間,傳統的責任鏈與裝飾者模式:https://www.cnblogs.com/SharePointApp/p/10340578.html 基本代碼 現在要做的就是責任鏈如果使用外置模式,能不能像裝飾者一樣幾個處理類聯合處理?答 ...
  • peewee 是一個輕量級的 Python ORM 框架,個人用下來感覺還好,簡單易上手,對於小項目能滿足大部分需求。peewee 的官方文檔沒有中文版的,網上的文章都是快速入門,抄了文檔中幾個例子,沒有詳細介紹的。本文略長,詳細介紹了增刪改查操作,並且詳解介紹了使用過程中遇到的各種問題。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...