淘寶垂直爬蟲之關鍵字搜索(實戰+源碼+可視化)

2021-02-21 IT加載中
1. 前言

上一篇博客 "爬蟲讓我再次在女同學面前長臉了~(現實版真實案例)" 說到了幫女同學批量下載試題,我把文章同步到了CSDN,竟然有41個贊 + 21個評論 + 155個收藏,難道大家和我的目的都一樣:爬蟲 liao mei ?

本篇文章主要介紹如何「快速」抓取淘寶商品信息,從幾個維度統計並且進行可視化,本次案例使用關鍵字 「安踏籃球鞋男鞋」,(僅僅是因為我最近買了一雙鞋子,然後就想到了這個商品而已)

2. 故事的背景

沒有故事,沒有背景,就是突然想。。。

3. 爬蟲的分類?

先來接地氣幾個詞,一般來說爬蟲可以分為 【通用爬蟲 、垂直爬蟲】,那麼是如何定義的呢?

通用爬蟲:通用爬蟲不需要理會網站哪些資源是需要的,哪些是不需要的,一併抓取並將其文本部分做索引(比如:百度爬蟲、搜狗爬蟲。。。)垂直爬蟲:垂直爬蟲往往在某一領域具有其專注性,並且垂直爬蟲往往只需要其中一部分具有垂直性的資源,所以垂直爬蟲相比通用爬蟲更加精確,這也是比較常見的爬蟲。

如果上面的解釋還不夠接地氣的話,舉個簡單例子小明想找一個女朋友,但是小明對女朋友要求為 null,只要 [ 是一個女的都行 ] 那種,這就可以理解為通用爬蟲;但是小明如果眼光比較挑,要求女朋友必須是 [ 身高165+,體重90,大眼睛,長頭髮,小蠻腰 ],這就可以理解為垂直爬蟲。

4. 淘寶對爬蟲有哪些限制?

淘寶爬蟲,很多文章都在講解淘寶登錄,然後分析ua參數等,以前我也很執著去分析過,真的挺難,後面我就沒有繼續跟下去了,就使用瀏覽器驅動實現登錄,如 selenium (需要修改參數,否則淘寶能識別) 或者 JxBrowser 等等。。。

除開淘寶登錄來看,淘寶的底線還是比較低的,暫時沒有很高防線,你攜帶 cookie 即可,沒錯就是攜帶「餅乾」給淘寶,他就給你通行了,所以本篇博客是通過攜帶 cookie 進行快速獲取到數據的,(個人:有時間就去學習逆向分析,但是真正實際爬的話,使用最低的成本獲取最高的效益,巧勁最大化

題外話,雖然說一般的大廠不輕易封IP (誤傷太大),但如果真的想海量採集淘寶商品數據的話,還必須要花點時間研究反爬策略的,否則很難進行海量抓取,因為文章後面有可能是有點觸發反爬了 (後面再說)

5. 抓包

如果在電腦首次上淘寶的話,你想搜索商品是必須要求登錄的,淘寶的要求登錄就不是我上一篇文章(撩妹佳文)那種假登錄限制了,而且整體接口都要求必須攜帶憑證(cookie)訪問的了,這裡介紹一個巧勁,因為如果使用登錄的 cookie 訪問淘寶的話,淘寶實際上是知道你是誰的,有你訪問的記錄的,然後你上淘寶可能會給你推送商品的,甚至對你帳號進行限制 、反爬等,因此寫一個爬蟲沒必要搭上那麼大的風險吧,所以登錄完成之後,就退出,這個時候瀏覽器還是可以正常搜索產品的,意思就是說不要使用登錄的 cookie 進行爬取數據。。。

五個抓包步驟如下

觀察 json 結構:複製上面的抓包的數據,然後進行 json 視圖查看

如何分頁?

上面的抓包只是一頁的數據,那麼如何抓取淘寶搜索其他頁呢?我可以直接告訴你的是,通過在 url 傳遞一個 s={最後一個商品的位置} 實現的分頁...

好吧   我們來簡單看一下吧:

在上面抓包中,我們並沒有看到 url 傳遞了 s 這個參數然後我們先來點擊一下 "下一頁",多點幾次觀察幾次,你就知道了 s 參數的變化了

觀察 s 變化,第二頁s=44,第三頁s=88,第四頁s=132,...

首頁沒有 s 參數
第二頁:https://s.taobao.com/search?q=%E5%AE%89%E8%B8%8F%E7%AF%AE%E7%90%83%E9%9E%8B%E7%94%B7%E9%9E%8B&imgfile=&js=1&stats_click=search_radio_all%3A1&initiative_id=staobaoz_20200705&ie=utf8&bcoffset=3&ntoffset=3&p4ppushleft=1%2C48&s=44
第三頁:https://s.taobao.com/search?q=%E5%AE%89%E8%B8%8F%E7%AF%AE%E7%90%83%E9%9E%8B%E7%94%B7%E9%9E%8B&imgfile=&js=1&stats_click=search_radio_all%3A1&initiative_id=staobaoz_20200705&ie=utf8&bcoffset=0&ntoffset=6&p4ppushleft=1%2C48&s=88
第三頁:https://s.taobao.com/search?q=%E5%AE%89%E8%B8%8F%E7%AF%AE%E7%90%83%E9%9E%8B%E7%94%B7%E9%9E%8B&imgfile=&js=1&stats_click=search_radio_all%3A1&initiative_id=staobaoz_20200705&ie=utf8&bcoffset=0&ntoffset=6&p4ppushleft=1%2C48&s=132

來到這裡,可以去掉其他不必要的參數,結論是:https://s.taobao.com/search?q={url encode keywords}&s={開始位置}

6. 編碼

經過上面繁瑣的步驟,終於可以著手編碼了,因為爬取數據之後需要進行可視化,所以數據肯定是需要持久化的,為了方便就保存到 csv 文件中。

逗號分隔值(Comma-Separated Values,CSV,有時也稱為字符分隔值,因為分隔字符也可以不是逗號),其文件以純文本形式存儲表格數據(數字和文本)。純文本意味著該文件是一個字符序列,不含必須像二進位數字那樣被解讀的數據。

在代碼裡注釋得很清楚的了,這裡直接貼代碼出來即可

為了簡潔,我貼出主要的代碼,想要獲取整體源碼項目的話,關注微信公告號( it_loading 回復 "淘寶爬蟲" 即可)

FastHttpClient.java

https://blog.csdn.net/JinglongSource/article/details/107136862

TaoBaoSpider1.java

import cn.shaines.spider.util.FastHttpClient;
import cn.shaines.spider.util.FastHttpClient.Response;
import cn.shaines.spider.util.FastHttpClient.ResponseHandler;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.hc.client5.http.classic.methods.HttpGet;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;

/**
 * @author for.houyu@qq.com
 */
@Slf4j
public class TaoBaoSpider1 {

    private static final String listUrlTemplate = "https://s.taobao.com/search?q=${keywords}&s=${index}";
    private static String cookie = "enc=l5xju4OJMzTwwtBkVJWbvFPcQ%2B6n6%2FWdRaE4iECxQOQiEtA45RBOyXQu0gZbOcIVEO6oxrRWvtu6mgSv4JZa8w%3D%3D; thw=cn; hng=CN%7Czh-CN%7CCNY%7C156; sgcookie=ESMDjIxrMIKwi48qmS8xP; tfstk=cCOGBNOa3dW_xoWHFf16ovEkfpHRZKNVqIRBTCGS8wNPBsdFiO2UUAat-GxMM-1..; tracknick=; cna=8XsbF0X0cVkCAbcg0Pt/qWLy; t=bb72251ba9e04aa4ffe5119a746b1f35; v=0; cookie2=1d43fd087e0cf8b4268f2e8ddcd4aea0; _tb_token_=e30835115bdfe; alitrackid=www.taobao.com; lastalitrackid=www.taobao.com; JSESSIONID=07CB217DBB9367EF2E0CCF7AF29AA9A0; isg=BDo6WaueMbQrb7zN4rxs3mhmi2Bc677FZ6MxoUQ_y0y9N99xLH6N1UYBh8PrpzZd; l=eBMkD1V4QZHXKy_vBO5whurza77ONdAfCsPzaNbMiInca6ZFN1uJuNQqG5uBldtjgtfj7etrb3kJjRUpziUdg2HvCbKrCyCk6Yp6-";

    private FastHttpClient httpClient;
    private BufferedWriter writer;
    private Set<String> filter;

    public static void main(String[] args) throws Exception {
        // 搜索關鍵字
        final String keywords = "安踏籃球鞋男鞋";
        // 每頁44條數據
        final int limit = 44;
        TaoBaoSpider1 spider = new TaoBaoSpider1();
        spider.init(keywords);
        for (int page = 0; page <= 99; page++) {
            log.info("正在準備下載頁數: {}", page + 1);
            String html = spider.getListHtml(keywords, page * limit);
            List<Goods> list  = spider.parse(html);
            log.info("解析得到數量: [{}]", list.size());
            if (list.isEmpty()) {
                break;
            }
            list = spider.doFilter(list);
            log.info("過濾後數量: [{}]", list.size());
            list.forEach(v -> {
                List<String> row = Arrays.asList(v.getRaw_title(), v.getView_price(), v.getView_fee(), v.getNick(), v.getItem_loc(), v.getView_sales(), v.getPic_url(), v.getDetail_url(), v.getComment_url(), v.getShopLink(), "_" + v.getNid(), "_" + v.getPid());
                spider.writeRow(row);
            });
            // 睡眠3 ~ 10秒
            Thread.sleep(ThreadLocalRandom.current().nextLong(3000, 10000));
            log.info("\r\n");
        }
    }

    private List<Goods> doFilter(List<Goods> list) {
        list = list.stream().filter(v -> !filter.contains(v.getNid())).collect(Collectors.toList());
        filter.addAll(list.stream().map(Goods::getNid).collect(Collectors.toSet()));
        return list;
    }

    /**
     * 寫入一行數據
     * @param row 一行數據
     */
    protected void writeRow(List<String> row) {
        // 寫入一行數據, csv的一行格式為,分割的, 但是這裡使用","分割,主要就是為了統一作為字符串
        // 如:
        //      "姓名","年齡"
        //      "張三","123"
        String line = row.stream().map(v -> v.replace("\"", "\"\"").replace(",", ",,")).collect(Collectors.joining("\",\"", "\"", "\""));
        try {
            writer.write(line);
            writer.newLine();
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 解析html
     * @param html the html
     */
    protected List<Goods> parse(String html) {
        if (StringUtils.isEmpty(html) || (html.contains("登錄頁面") && html.contains("全登陸不允許iframe嵌入"))) {
            throw new RuntimeException("獲取列表HTML失敗,請檢查,如更新cookie等...");
        }
        String script = Arrays.stream(StringUtils.substringsBetween(html, "<script", "</script>"))
                // 過濾包含 g_page_config 和 auctions 的 script 腳本
                .filter(v -> v.contains("g_page_config") && v.contains("itemlist"))
                // 獲取第一個符合條件的腳本(原則來上說這裡只能返回一個, 否則說明上面的過濾不嚴謹)
                .findFirst()
                // 如果沒有匹配的就拋異常, 說明解析頁面失敗
                .orElseThrow(() -> new RuntimeException("解析頁面失敗,請檢查更新代碼"));
        // 觀察 script 內部其實是一個json格式的字符串, 因此找到分割點進行切割字符串返回一個json串
        String json = StringUtils.substringBetween(script, "g_page_config", "g_srp_init");
        json = json.substring(json.indexOf("{"), json.lastIndexOf("}") + 1);
        // 使用 JSONPath 實現快速解析json, 這裡的意思是查找n級 itemlist 下的 n級auctions (說明:alibaba fastjson 就有 JSONPath 的實現)
        Object eval = JSONPath.eval(JSON.parseObject(json), "$..itemlist..auctions");
        if (!(eval instanceof List)) {
            throw new RuntimeException("解析JSON列表失敗, 請檢查更新代碼");
        }
        List<JSONObject> auctions = (List<JSONObject>) eval;
        // 轉換為目標對象 Goods
        List<Goods> result = auctions.stream().map(v -> v.toJavaObject(Goods.class)).collect(Collectors.toList());
        // result.forEach(System.out::println);
        return result;
    }

    /**
     * 根據關鍵字獲取列表HTML
     * @param keywords 關鍵字 如: 安踏籃球鞋男鞋
     * @param index 開始位置, 如0, 每頁顯示44條數據, 因此0, 44, 88, ...
     */
    protected String getListHtml(String keywords, int index) {
        // 中文進行URL編碼
        keywords = FastHttpClient.encodeURLText(keywords, StandardCharsets.UTF_8);
        String url = listUrlTemplate.replace("${keywords}", keywords).replace("${index}", index + "");
        // 創建一個GET請求
        HttpGet httpGet = httpClient.buildGet(url);
        // 執行請求, 獲取響應
        Response<String> response = httpClient.execute(httpGet, ResponseHandler.ofString());
        return response.getData();
    }

    /**
     * 資源初始化
     */
    protected void init(String keywords) {
        // 初始化 httpClient 並且設置 cookie 每次請求都會攜帶cookie信息
        httpClient = FastHttpClient.builder().setCookie(cookie).build();
        filter = new HashSet<>(1024);
        try {
            // 初始化 CSV 文件呢
            File file = Paths.get(System.getProperty("user.dir"), "temp", "spider", keywords + ".csv").toFile();
            file.getParentFile().mkdirs();
            writer = new BufferedWriter(new FileWriter(file, false));
            // 準備header
            List<String> header = Arrays.asList("標題", "單價", "運費", "店名", "發貨地址", "售量", "首頁圖", "明細地址", "評論地址", "購買地址", "nid", "pid");
            this.writeRow(header);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static class Goods {
        /** nid */
        private String nid;
        /** pid */
        private String pid;
        /** 標題 */
        private String raw_title;
        /** 首頁圖 */
        private String pic_url;
        /** 明細地址 */
        private String detail_url;
        /** 單價 */
        private String view_price;
        /** 運費 */
        private String view_fee;
        /** 發貨地址 */
        private String item_loc;
        /** 售量 */
        private String view_sales;
        /** 店名 */
        private String nick;
        /** 評論地址 */
        private String comment_url;
        /** 購買地址 */
        private String shopLink;

        public String getNid() {
            return nid;
        }

        public void setNid(String nid) {
            this.nid = nid;
        }

        public String getPid() {
            return pid;
        }

        public void setPid(String pid) {
            this.pid = pid;
        }

        public String getRaw_title() {
            return raw_title;
        }

        public void setRaw_title(String raw_title) {
            this.raw_title = raw_title;
        }

        public String getPic_url() {
            return pic_url;
        }

        public void setPic_url(String pic_url) {
            this.pic_url = pic_url;
        }

        public String getDetail_url() {
            return detail_url;
        }

        public void setDetail_url(String detail_url) {
            this.detail_url = detail_url;
        }

        public String getView_price() {
            return view_price;
        }

        public void setView_price(String view_price) {
            this.view_price = view_price;
        }

        public String getView_fee() {
            return view_fee;
        }

        public void setView_fee(String view_fee) {
            this.view_fee = view_fee;
        }

        public String getItem_loc() {
            return item_loc;
        }

        public void setItem_loc(String item_loc) {
            this.item_loc = item_loc;
        }

        public String getView_sales() {
            return view_sales;
        }

        public void setView_sales(String view_sales) {
            this.view_sales = view_sales;
        }

        public String getNick() {
            return nick;
        }

        public void setNick(String nick) {
            this.nick = nick;
        }

        public String getComment_url() {
            return comment_url;
        }

        public void setComment_url(String comment_url) {
            this.comment_url = comment_url;
        }

        public String getShopLink() {
            return shopLink;
        }

        public void setShopLink(String shopLink) {
            this.shopLink = shopLink;
        }

        @Override
        public String toString() {
            final StringBuilder sb = new StringBuilder("Goods{");
            sb.append("nid='").append(nid).append('\'');
            sb.append(", pid='").append(pid).append('\'');
            sb.append(", raw_title='").append(raw_title).append('\'');
            sb.append(", pic_url='").append(pic_url).append('\'');
            sb.append(", detail_url='").append(detail_url).append('\'');
            sb.append(", view_price='").append(view_price).append('\'');
            sb.append(", view_fee='").append(view_fee).append('\'');
            sb.append(", item_loc='").append(item_loc).append('\'');
            sb.append(", view_sales='").append(view_sales).append('\'');
            sb.append(", nick='").append(nick).append('\'');
            sb.append(", comment_url='").append(comment_url).append('\'');
            sb.append(", shopLink='").append(shopLink).append('\'');
            sb.append('}');
            return sb.toString();
        }
    }

}

7. 運行代碼

效果如下

文件保存路徑默認在項目路徑 $/temp/spider/xxx.csv

一共爬了2074條數據,爬到大概50頁的時候,發現返回的數據都是重複的了(根據nid過濾)大概猜測原因:

淘寶限制返回數量(雖然寫著99頁,實際真實客戶也不可能是真的翻了99頁找商品...)8. 數據可視化

以下可視化數據僅供學習參考,不具備任何依據判斷,不承擔任何責任。

1. 淘寶 - 安踏籃球鞋男鞋 - 發貨地詞雲圖

2. 淘寶 - 安踏籃球鞋男鞋 - 店鋪售量衝浪榜

僅展示店鋪售量1900+以上店鋪,不上榜的店鋪納入 「其他」

3. 淘寶 - 安踏籃球鞋男鞋 - 價格&售量表1

4. 淘寶 - 安踏籃球鞋男鞋 - 價格&售量表2

9. 擴展

上面的代碼完成一個關鍵字的搜索,頂多可以算一個爬蟲,並不能算一個完整的爬蟲系統,一個爬蟲系統應該具備以下的幾個組件。(待完善)

相關焦點

  • python爬蟲之selenium抓取淘寶商品信息
    簡介本節採用python爬蟲相關技術獲取淘寶商品信息。採用的技術有selenium、pyquery及urllib.parse等。接下去需要按F12查看並分析淘寶登錄界面的元素信息(見圖1),獲取輸入框和按鈕的相關信息,以便我們使用selenium模擬用戶登錄,登陸後搜索關鍵信息。
  • 如何快速學會Python爬蟲(入門篇)
    Python爬蟲入門七之正則表達式二、爬蟲實戰Python爬蟲實戰一之爬取糗事百科段子2.Python爬蟲實戰二之爬取百度貼吧帖子3. Python爬蟲實戰三之實現山東大學無線網絡掉線自動重連4. Python爬蟲實戰四之抓取淘寶MM照片5. Python爬蟲實戰五之模擬登錄淘寶並獲取所有訂單6.
  • 用Python分析淘寶2000款保險套,得出這些有趣的結論
    點擊上方「Python技術之巔」,馬上關注,每天下午
  • 實戰|Python輕鬆實現動態網頁爬蟲(附詳細源碼)
    大家好,我是J哥,專注原創,致力於用淺顯易懂的語言分享爬蟲、數據分析及可視化等乾貨,希望人人都能學到新知識。
  • 用案例讓你一文搞懂python網絡爬蟲
    很久以前寫了一篇爬蟲的文章,把它放在CSDN上(livan1234)沒想到點擊量竟然暴漲,足以看到大家在數據獲取方面的需求,爬蟲技術現在已經非常普遍,其用途也非常廣泛,很多牛人在各個領域做過相關的嘗試,比如: 1)爬取汽車之家數據,利用論壇發言的抓取以及NLP,對各種車型的車主做畫像。
  • 淺談開源的可視化建站類程序源碼
    1:建站之星如果說可視化建站系統最久遠的,那絕對是建站之星2.7了,網上找了還附送3000套模板和視頻的。筆者滿懷希望的花了19.9在某站網上下的,結果下載後,震驚。裡面的樣式,UI,甚至功能都是很L*W的。不過筆者也是拿來學習的,說實話沒怎麼做過研究。
  • 從零開始的python爬蟲速成指南
    一、爬蟲入門Python爬蟲入門一之綜述Python爬蟲入門二之爬蟲基礎了解Python爬蟲入門三之Urllib庫的基本使用Python爬蟲入門四之Urllib庫的高級用法Python爬蟲入門五之URLError異常處理Python爬蟲入門六之Cookie的使用
  • 如何爬取全網1200本Python書|爬蟲實戰篇
    這是菜鳥學Python
  • Python網絡爬蟲實戰(一)快速入門
    本系列從零開始闡述如何編寫Python網絡爬蟲,以及網絡爬蟲中容易遇到的問題,比如具有反爬,加密的網站,還有爬蟲拿不到數據,以及登錄驗證等問題
  • 《知識圖譜完整項目實戰》學習指引
    一、前言本文是《知識圖譜完整項目實戰(附源碼)》系列課程的學習指引部分,主要是對《知識圖譜完整項目實戰》的課程特色、章節設置、關鍵技術和主要內容做一個簡介,目的是讓大家對本課程有一個系統性的認知。包括:需求分析、架構設計、知識建模、知識抽取、可視化展示等;課程特色2:實戰開發:從0-1,全面剖析完整項目整個建設生命周期:知識抽取、知識建模、知識推理、知識存儲、知識應用;課程特色3
  • Python爬蟲入門教程:超級簡單的Python爬蟲教程
    這是一篇詳細介紹 Python 爬蟲入門的教程,從實戰出發,適合初學者。讀者只需在閱讀過程緊跟文章思路,理清相應的實現代碼,30 分鐘即可學會編寫簡單的 Python 爬蟲。;今天給大家講第一課了解網頁;以中國旅遊網首頁為例,抓取中國旅遊網首頁首條信息(標題和連結),數據以明文的形式出面在源碼中。
  • 床長人工智慧教程pdf下載網校——Python爬蟲實戰八
    項目提供了如下功能輸入淘寶關鍵字採集淘寶連結並寫入到文件從文件讀取連結,執行評論採集將評論和旺旺號保存到中記錄當前採集連結索引,保存進度準備工作實戰爬取抓取過程首先我們觀察這個連結,在最初的時候,其實網頁並沒有加載最下方的看了又看內容的,慢慢往下滑動網頁,滑到最下方之後,才發現看了又看頁面才慢慢加載出來。
  • Google Play Store關鍵字搜索優化
    標題關鍵字至關重要。 舉例:輸入」kill apps」或者 「clean residual」,Top結果中出現遊戲類、金融類的應用,明顯跟搜索意向不在同一範疇。這些應用僅在標題處帶了相應的關鍵字,詳情描述中並無,可見標題的關鍵字影響重大。
  • 可視化大屏來幫忙!
    作者:黃偉呢來源:數據分析與統計學之美案例背景 歡迎來到
  • 爬蟲大殺器 | Python學習之Scrapy-Redis實戰京東圖書
    scrapy-redis的源碼中提供了scrapy-redis的示例項目,我們下載下來學習一下。本次主要是對dmoz這個demo進行學習和實戰練習。: div.css('.site-descr::text').extract_first().strip(),                'link': div.css('a::attr(href)').extract_first(),            }可以看到,dmoz項目和我們平時創建的scrapy項目並沒有太大的區別,之所以能夠實現持久化爬蟲主要的不同之處在
  • 網絡爬蟲違法?扯!繼續學習我的第一個爬蟲
    隨著資訊時代的迭代更新,人工智慧的興起,Python程式語言也隨之被人們廣泛學習,Python數據分析、Python web全棧、Python自動化運維等等都很受歡迎,其中還包括了Python爬蟲。但是很對人覺得Python爬蟲是違法的行為,也在懷疑自己到底要不要學爬蟲,之前有一篇文章特別火,就是《 只因寫了一段爬蟲,公司200多人被抓!》
  • 福利 | 精選幾本 Python 爬蟲的經典書,免費送你
    二、Python爬蟲開發與項目實戰、爬蟲的異常處理、正則表達式、爬蟲中Cookie的使用、爬蟲的瀏覽器偽裝技術、定向爬取技術、反爬蟲技術,以及如何自己動手編寫網絡爬蟲; 工具維度:以流行的Python網絡爬蟲框架Scrapy為對象,詳細講解了Scrapy的功能使用、高級技巧、架構設計、實現原理,以及如何通過Scrapy來更便捷、高效地編寫網絡爬蟲; 實戰維度:以實戰為導向,是本書的主旨,除了完全通過手動編程實現網絡爬蟲和通過Scrapy
  • 資料|精通 Python 網絡爬蟲:核心技術、框架與項目實戰
    本書從系統化的視角,為那些想學習Python網絡爬蟲或者正在研究Python網絡爬蟲的朋友們提供了一個全面的參考,讓讀者可以系統地學習Python網絡爬蟲的方方面面,在理解並掌握了本書的實例之後,能夠獨立編寫出自己的Python網絡爬蟲項目,並且能夠勝任Python網絡爬蟲工程師相關崗位的工作。
  • 實戰 | 源碼入門之Faster RCNN
    網上有很多版本的Faster RCNN的源碼,但是很多版本代碼太過於龐大,對新入門的學習者學習起來很不友好,在網上苦苦尋找了一番後終於找到了一個適合源碼學習的Faster Rcnn的pytorch版本代碼。根據該版本的作者講該代碼除去注釋只有兩千行左右,並且經過小編的一番學習之後,發現該版本的代碼真的是非常的精簡幹練,讀起來「朗朗上口」,並且深刻的感覺到作者代碼功底之深厚。