12.爬蟲

原生爬蟲

真正的爬蟲功能非常復雜:
比如反爬機制、自動登錄、代理IP等輔助功能
演示python小工具項目應該遵守的規范
順便通過小案例,聊一下好代碼應該如何編寫
1.鞏固知識
2.合理編碼方式
3.了解爬蟲基本原理

最開始爬豆瓣
爬取熊貓TV
爬取某個游戲分類下面,主播的人氣排行

整理爬蟲常規思路

利用chorme查看html結構。
主播名字、觀看人數
無論簡單的爬蟲還是復雜的爬蟲,都是通過分析html提取所需要的信息。

爬蟲的前奏:
1.明確目的 -- 某一類游戲的主播的排名
2.找到數據的網頁

  1. 分析網頁的結構、找到數據所在的標簽位置

模擬http請求,向服務器發送請求,獲取服務器返回給我們的html
用正則表達式提取我們需要的數據

vscode中調試代碼

斷點調試 非常重要
python自帶的 assert 也是好久沒用過了?

html結構分析基本原則 二條

抓取的html為bytes,可以采用str函數轉換格式
htmls = str(htmls, encodeing="utf-8)
尋找標簽:通過標簽定位所需要的信息。

數據提取層分析及 原則三

3.選擇標簽時,盡量選取可以閉合的標簽。同時將需要爬取的一組數據包裹起來,防止分開爬取

正則分析html

正則分析獲取名字和人數

數據精煉

sorted排序

案例總結

import re
from urllib import request


class Spider(object):
    url = "https://www.panda.tv/cate/lol?pdt=1.24.s1.3.7udc0vft7s5"
    # reg = re.compile(
    #     r"""<div[\s]*?class="video-info">[\s\S]*?nickname"[\s]*?title="([\s\S]*?)">[\s\S]*?number">([\s\S]*?)</span>"""
    # )
    # 匹配全部內容 -> [\s\S]  . [\d\D] [\w\W]
    root_pattern = '<div class="video-info">([\s\S]*?)</div>'
    name_pattern = '[\s\S]*?nickname"[\s]*?title="([\s\S]*?)">'
    number_pattern = '[\s\S]*?number">([\s\S]*?)</span>'

    def __feach_content(self):
        r = request.urlopen(Spider.url)
        htmls = r.read()
        return htmls

        # assert htmls, "沒有返回值"
        # with open("test.txt", "wb") as f:
        #     f.write(htmls)

    def __analysis(self, htmls):
        # result = Spider.reg.findall(htmls)
        # print(result)
        root_html = re.findall(Spider.root_pattern, htmls)
        re_dict = []
        for result in root_html:
            name = re.findall(Spider.name_pattern, result)
            number = re.findall(Spider.number_pattern, result)
            anchor = {"name": name, "number": number}
            re_dict.append(anchor)

        return re_dict

    def __refine(self, re_dict):
        l = lambda re_dict:{"name": re_dict["name"][0], "number": re_dict["number"][0]}
        return map(l, re_dict)

    def __sort(self, re_dict):
        re_dict = sorted(re_dict, key=self.__sort_seed, reverse=True)
        return re_dict

    def __sort_seed(self, re_dict):  # 排序種子,對應re_dict的一個元素
        r = re.findall("\d*", re_dict["number"])
        number = float(r[0])
        if "萬" in re_dict["number"]:
            number *= 10000

        return number

    def __show(self, re_dict):
        for rank in range(0, len(re_dict)):
            print("rank:" + str(rank + 1) + "---" + re_dict[rank]["name"] + "----" + re_dict[rank]["number"])

    def go(self):
        htmls = self.__feach_content()
        htmls = htmls.decode("utf-8")  # 提取大塊數據
        re_dict = self.__analysis(htmls)  # 分析數據
        re_dict = self.__refine(re_dict)  # 數據精煉
        re_dict = self.__sort(re_dict)
        self.__show(re_dict)


spider = Spider()
spider.go()
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容