python爬蟲抓取app列表的圖標

python爬蟲抓取app列表的圖標


爬蟲簡介

所謂的爬蟲簡單來說,就是通過不斷的變化http請求的url,向服務器進行請求,從而獲得服務器返回的相關數據,在這些數據中提取對自己有用的信息。

爬蟲的步驟

  • 構造url。根據自己想要抓取的信息,構造出相應的url。
  • 請求url。根據上面構造的url,向服務器發起請求。(在python中可以用urllib、request庫等)
  • 提取數據。向服務器發起請求后,服務器會返回相關的數據(如:html、json、xml),在這些數據中提取對自己有用的信息(可以用正則表達式、BeautifulSoup、json、lxml等)。
  • 保存數據。已特定的格式(csv文件)保存上面提取的數據,以便于后面進行數據分析。

例子

使用爬蟲抓取app列表的圖標,如微信、QQ、今日頭條等。

  • 構造url
    打開豌豆莢首頁,在搜索框中輸入微信,進行搜索。豌豆莢服務器返回下圖的頁面,有搜索到app列表的信息和圖標。
weixin.png

在進行搜索時,用Wireshark進行抓包,可以看到在搜索微信時,對應的http請求為:http://www.wandoujia.com/search?key=%E5%BE%AE%E4%BF%A1&source=index
QQ的請求為:
http://www.wandoujia.com/search?key=QQ&source=index
今日頭條的請求為:
http://www.wandoujia.com/search?key=%E4%BB%8A%E6%97%A5%E5%A4%B4%E6%9D%A1&source=index

  • 從上面的3個不同的app的http請求,我們可以發現,只是搜索的key值有所不同,比如微信的key為%E5%BE%AE%E4%BF%A1,QQ的key為QQ,今日頭條的key為%E5%BE%AE%E4%BF%A1。這些值對應字符的utf-8編碼 + url編碼。也是說微信的utf-8為E5 BE AE E4 BF A1,格式化為url編碼就是:%E5%BE%AE%E4%BF%A1。
  • 所以對于不同的app應用要構造出不同請求的url,我們只需要改變上面http請求的key值,再向豌豆莢的服務器發送請求即可。

請求url

在python中可以使用urllib、request庫等。

提取數據

發送http請求后,豌豆莢服務器會返回搜索的app列表。可以看到是一個html文檔。用Chrome瀏覽器,查看返回的html文檔,定位到相關的信息。如下圖,可以看到,微信的圖標的鏈接地址。這就是我們需要提取的數據。

img_link.png

在python中我們可以使用正則表達式來提取圖標的鏈接地址,或者對于html可以使用BeautifulSoup來提取。

保存數據

上面提取的是圖標的鏈接地址,我們可以再次用這個鏈接地址發起http請求,就可以得到相應圖標的數據,然后把數據保存到磁盤中即可。


代碼如下:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""從豌豆莢應用市場抓取app列表的圖標"""

from urllib.parse import quote
from urllib import request
from functools import wraps
import re


__author__ = 'heql'


def url_decorate(func):

    @wraps(func)
    def wrapper(*args, **kwargs):
        print(*args)
        if args:
            return func(*args)
    return wrapper


@url_decorate
def request_url(url):
    """請求url"""
    cnt = 3
    for i in range(cnt):
        try:
            with request.urlopen(url, timeout=20) as f:
                return f.read()
        except Exception as e:
            if(i < cnt - 1):
                print('request again')
            else:
                print('except:', e)


def save_icon(file_name, data):
    with open(file_name, 'wb') as f:
        f.write(data)                


def get_icon_links(data, app_name, compare=None):
    """提取圖標的鏈接"""
    items = re.findall(r'(<div class="icon-wrap">(?:.|\n)*?</h2>)', data)

    for item in items:
        icon_link = re.search(r'<img src="(.*?)"', item).group(1)
        icon_app_name = re.search(r'class="name">(.*?)</a>', item).group(1)

        result = True if compare is None else compare(icon_app_name, app_name)
        if result:
            yield icon_app_name, icon_link
   

def read_app_list(file_name):
    """讀取app列表"""
    with open(file_name, encoding='utf-8') as f:
        return [line.strip() for line in f if line.strip()]


def main():
    app_name_list = read_app_list('app_list.txt')
    url  = 'http://www.wandoujia.com/search?key={0}&source=index'

    for app_name in app_name_list:
        data = request_url(url.format(quote(app_name, encoding='utf-8')))
        if not data:
            continue

        for index, (icon_app_name, icon_link) in enumerate(get_icon_links(data.decode('utf-8'), app_name, lambda left, right: left == right)):
            icon_data = request_url(icon_link)
            if not icon_data:
                continue

            file_name = '{0}_{1}.png'.format(icon_app_name, index)
            save_icon(file_name, icon_data)             
    

if __name__ == '__main__':
    main()

代碼分析:

read_app_list函數: 從文件中讀出app列表的名稱,每一行對應一個app名稱。

request_url函數: 使用urllib發送http請求。如果請求時發生異常(如:網絡超時、url請求錯誤等),則再次發送請求,如果同一個url超過三次請求有誤,則返回None。它有一個裝飾器url_decorate,用于輸出發送請求時的url。

get_icon_links函數: 用于提取服務器返回的數據。使用正則表達式findall匹配所有符合以<div class="icon-wrap">開始,以/h2>結束的選項。findall會返回一個list。然后對每個選項用整個表達式提取圖標的鏈接和圖標的名稱。compare 是一個回調函數,當為None時表示要提取所有的圖標信息,代碼傳入一個lambda表達式,lambda left, right: left==right表示只有提取的圖標名稱和搜索的圖標的名稱相同時,才返回其對應的圖標鏈接。

save_icon函數: 寫入圖標的數據到指定的文件中。圖標保存的名稱是以名字_下標形式保存的,因為有可能會出現兩個以上名字相同的數據,比如說:搜索可可英語。會有兩個相同的app名稱的應用。


使用BeautifulSoup提取html數據

Beautiful Soup 是一個可以從HTML或XML文件中提取數據的Python庫。

參考: https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html

使用BeautifulSoup后能讓代碼更加簡潔,對于上面的程序,我們只需修改get_icon_links即可。代碼如下:

# 提取圖標的鏈接
def get_icon_links(data, app_name, compare=None):
    soup = BeautifulSoup(data, 'lxml')
    for tag in soup.find_all('img'):
        icon_link = tag['src']
        icon_app_name = tag['alt']

        result = True if compare is None else compare(icon_app_name, app_name)
        if result:
            yield icon_app_name, icon_link
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,443評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,530評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,407評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,981評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,759評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,204評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,263評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,415評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,955評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,650評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,892評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,675評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,967評論 2 374

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,783評論 18 139
  • WebSocket-Swift Starscream的使用 WebSocket 是 HTML5 一種新的協議。它實...
    香橙柚子閱讀 23,989評論 8 183
  • 聲明:本文講解的實戰內容,均僅用于學習交流,請勿用于任何商業用途! 一、前言 強烈建議:請在電腦的陪同下,閱讀本文...
    Bruce_Szh閱讀 12,753評論 6 28
  • 遇見 在這個深秋,在這條路上,我遇見了你一一簡書, 已是深秋,只有涼意一絲絲, 我取名為一一深秋好個涼, 愿我們的...
    深秋好個涼閱讀 384評論 0 1
  • 今天繼續利用空閑的時間學習敬天愛人,在之前的學習中,一直沒有對敬天愛人的概念進行系統的歸納總結。隨著學習深度的加...
    林賢閱讀 265評論 0 1