1. 程式人生 > >【Python實戰】機型自動化標註(搜狗爬蟲實現)

【Python實戰】機型自動化標註(搜狗爬蟲實現)

1. 引言

從安卓手機收集上來的機型大都為這樣:

mi|5
mi|4c
mi 4c
2014022
kiw-al10
nem-tl00h

收集的機型大都雜亂無章,不便於做統計分析。因此,標註顯得尤為重要。

中關村線上有對國內大部分手機的介紹情況,包括手機機型nem-tl00h及其對應的常見名稱榮耀暢玩5C。因而,設計機型自動化標註策略如下:

  1. 在搜狗搜尋中輸入機型進行搜尋,為了限定第一個返回結果為ZOL網站,加上限定詞site:detail.zol.com.cn
  2. 通過第一條返回結果的連結,跳轉到相應的ZOL頁面,解析拿到標註名稱與手機別名。

2. 實現

根據上面的爬取策略,我用Python實現一個簡單的爬蟲:採用

PyQuery解析HTML頁面,PyQuery採用類似jQuery的語法來操作HTML元素,熟悉jQuery的人對PyQuery是上手即用。

Sogou爬蟲的程式碼實現(基於Python 3.5.2)如下:

# -*- coding: utf-8 -*-
# @Time    : 2016/8/8
# @Author  : rain
import codecs
import csv
import logging
import re
import time
import urllib.parse
import urllib.request
import urllib.error

from pyquery import PyQuery as pq


def quote_url(model_name):
    base_url = "https://www.sogou.com/web?query=%s"
    site_zol = "site:detail.zol.com.cn "
    return base_url % (urllib.parse.quote(site_zol + model_name))


def parse_sogou(model_name):
    search_url = quote_url(model_name)
    request = urllib.request.Request(url=search_url, headers={
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
                      'Chrome/45.0.2454.101 Safari/537.36'})
    sogou_html = urllib.request.urlopen(request).read()
    sogou_dom = pq(sogou_html)
    goto_url = sogou_dom("div.results>.vrwrap>.vrTitle>a[target='_blank']").eq(0).attr("href")
    logging.warning("goto url: %s", goto_url)
    if goto_url is None:
        return None
    goto_dom = pq(url=goto_url)
    script_text = goto_dom("script").text()
    zol_url = re.findall(r'\("(.*)"\)', script_text)[0]
    return zol_url


def parse_zol(model_name):
    zol_url = parse_sogou(model_name)
    if zol_url is None:
        return None, None
    try:
        zol_html = urllib.request.urlopen(zol_url).read()
    except urllib.error.HTTPError as e:
        logging.exception(e)
        return None, None
    zol_dom = pq(zol_html)
    title = zol_dom(".page-title.clearfix")
    name = title("h1").text()
    alias = title("h2").text()
    if u'(' in name and u')' in name:
        match_result = re.match(u'(.*)((.*))', name)
        name = match_result.group(1)
        alias = match_result.group(2) + " " + alias
    return name, alias


if __name__ == "__main__":
    with codecs.open("./resources/data.txt", 'r', 'utf-8') as fr:
        with open("./resources/result.csv", 'w', newline='') as fw:
            writer = csv.writer(fw, delimiter=',')
            for model in fr.readlines():
                model = model.rstrip()
                label_name, label_alias = parse_zol(model)
                writer.writerow([model, label_name, label_alias])
                logging.warning("model: %s, name: %s, alias: %s", model, label_name, label_alias)
                time.sleep(10)

為了防止sogou封禁,每爬一次則休息10s。當然,這種爬取的速度會非常慢,需要做些優化。

3. 優化

下載驗證碼

sogou是通過訪問頻次來進行封禁,當訪問次數過多時,會要求輸入驗證碼:

<div class="content-box">
    <p class="ip-time-p">IP:61...<br/>訪問時間:2016.08.09 15:40:04</p>
    <p class="p2">使用者您好,您的訪問過於頻繁,為確認本次訪問為正常使用者行為,需要您協助驗證。</p>
    ...
    <form name="authform" method="POST" id="seccodeForm" action="/">
        <p class="p4">
            ...
            <input type="hidden" name="m" value="0"/>            <span class="s1">
                <a onclick="changeImg2();" href="javascript:void(0)">
                    <img id="seccodeImage" onload="setImgCode(1)" onerror="setImgCode(0)" src="util/seccode.php?tc=1470728404" width="100" height="40" alt="請輸入圖中的驗證碼" title="請輸入圖中的驗證碼"/>
                </a>
            </span>
            <a href="javascript:void(0);" id="change-img" onclick="changeImg2();" style="padding-left:50px;">換一張</a>
            <span class="s2" id="error-tips" style="display: none;"/>
        </p>
    </form>
    ...
</div>

通過分析html,真實的驗證碼影象需要做如下的拼接:

http://weixin.sogou.com/antispider/util/seccode.php?tc=1470728404

下載驗證碼影象到本地:

import urllib.request
from pyquery import PyQuery as pq
import re


for i in range(100):
    html = urllib.request.urlopen("https://www.sogou.com/web?query=treant").read()
    dom = pq(html)
    img_src = dom("#seccodeImage").attr("src")
    if img_src is not None:
        img_name = re.search("tc=(.*)", img_src).group(1)
        anti_img_url = "http://weixin.sogou.com/antispider/" + img_src
        urllib.request.urlretrieve(anti_img_url, "./images/" + img_name + ".jpg")

tesseract識別驗證碼,識別的效果的一般,等以後有時間再考慮下其他識別方法。

相關推薦

Python實戰機型自動化標註爬蟲實現

1. 引言 從安卓手機收集上來的機型大都為這樣: mi|5 mi|4c mi 4c 2014022 kiw-al10 nem-tl00h 收集的機型大都雜亂無章,不便於做統計分析。因此,標註顯得尤為重要。 中關村線上有對國內大部分手機的介紹情況,包括手機機型nem-tl00h及其對應的常見名稱榮耀暢玩5C

Python實戰Pandas:讓你像寫SQL一樣做資料分析

1. 引言 前一篇介紹了Pandas實現簡單的SQL操作,本篇中將主要介紹一些相對複雜一點的操作。為了方便後面實操,先給出一份簡化版的裝置統計資料: 0 android NLL 387546520 2099457911 0 ios NLL 52877990 916421755 1 and

Python實戰Pandas:讓你像寫SQL一樣做資料分析

1. 引言 Pandas是一個開源的Python資料分析庫。Pandas把結構化資料分為了三類: Series,1維序列,可視作為沒有column名的、只有一個column的DataFrame; DataFrame,同Spark SQL中的DataFrame一樣,其概念來自於R語言,為多column並sch

AI實戰快速掌握TensorFlow:激勵函式

到現在我們已經瞭解了TensorFlow的特點和基本操作(見文章:快速掌握TensorFlow(一)),以及TensorFlow計算圖、會話的操作(見文章:快速掌握TensorFlow(二)),接下來我們將繼續學習掌握TensorFlow。 本文主要是學習掌握TensorFlow的激勵函式

AI實戰基礎環境搭建Ubuntu+conda+tensorflow+GPU+PyCharm

為方便日常的深度學習模型開發與測試,在自己筆記本上搭建一個深度學習的基礎環境,便於學習AI使用。本人使用的筆記本配置是CPU為8代i5,顯示卡為GTX1060,記憶體為8G,基本上可滿足日常的AI研究與學習。下面將介紹基礎環境的搭建配置過程: 1、安裝Ubuntu 18.04

AI實戰快速掌握TensorFlow:計算圖、會話

在前面的文章中,我們已經完成了AI基礎環境的搭建(見文章:Ubuntu + Anaconda + TensorFlow + GPU + PyCharm搭建AI基礎環境),以及初步瞭解了TensorFlow的特點和基本操作(見文章:快速掌握TensorFlow(一)),接下來將繼續學習掌握Tenso

AI實戰快速掌握Tensorflow:基本操作

Tensorflow是Google開源的深度學習框架,來自於Google Brain研究專案,在Google第一代分散式機器學習框架DistBelief的基礎上發展起來。Tensorflow於2015年11月在GitHub上開源,在2016年4月補充了分散式版本,最新版本為1.10,2018年

AI實戰快速掌握TensorFlow:損失函式

在前面的文章中,我們已經學習了TensorFlow激勵函式的操作使用方法(見文章:快速掌握TensorFlow(三)),今天我們將繼續學習TensorFlow。 本文主要是學習掌握TensorFlow的損失函式。 一、什麼是損失函式 損失函式(loss function)是機器學習

Python實戰用Scrapyd把Scrapy爬蟲一步一步部署到騰訊雲

將我們的爬蟲部署到騰訊雲伺服器上面。廢話不多說,我們就來實戰操作吧。 這裡選擇什麼雲服務都是可以的,阿里雲,AWS,騰訊雲,其他雲都是沒有問題的。部署方法基本一樣,這裡為了方便,所以筆者選擇了騰訊雲來做講解。 既然我們選擇了騰訊雲,首先去騰訊雲的官網,註冊登入一下。 點選複製https:

python基礎面向物件程式設計初級篇

在Python教學中發現,很多同學在走到面向物件程式設計這塊就開始蒙圈了,為了幫助大家更好的理解面向物件程式設計並其能將其用到自己的開發過程中,特寫此文。 概述 面向過程:根據業務邏輯從上到下寫壘程式碼 函式式:將某功能程式碼封裝到函式中,日後便無需重複

專案實戰——Java根據獎品權重計算中獎概率實現抽獎適用於砸金蛋、大轉盤等抽獎活動

  雙蛋節(聖誕+元旦)剛剛過去,前幾天專案上線的砸金蛋活動也圓滿結束。       現在在許多網站上都會有抽獎的活動,抽獎的演算法也是多種多樣,這裡介紹一下如何根據每種獎品的權重來抽獎,適用於

Python實戰Scrapy豌豆莢應用市場爬蟲

對於給定的大量APP,如何爬取與之對應的(應用市場)分類、描述的資訊?且看下面分解。 1. 頁面分析 當我們在豌豆莢首頁搜尋框輸入微信後,會跳轉到搜尋結果的頁面,其url為http://www.wandoujia.com/search?key=%微信。搜尋結果一般是按相關性排序的;所以,我們認為第一條搜尋結果

Python實戰Django建站筆記

前一段時間,用Django搭建一個報表分析的網站;藉此正好整理一下筆記。 1. 安裝 python有包管理工具pip,直接cd Python27/Scripts,輸入 pip install django # install by version pip install --upgrade Django==

Dubbo實戰基礎學習篇

Dubbo的簡介是什麼?Dubbo是阿里巴巴SOA服務化治理方案的核心框架,每天為2,000多個服務提供30多億次訪問量支援,並被廣泛應用於阿里巴巴集團的各成員站點。Dubbo是一個分散式服務框架,致力

web前端第二篇HTML基礎二表單、div

ebe add 渲染 efi end 文件 ctype 發送 type 一、表單 功能:表單用於向服務器傳輸數據,從而實現用戶與Web服務器的交互 表單能夠包含input系列標簽,比如文本字段、復選框、單選框、提交按鈕等等。 表單還可以包含text

TOJ 3955NKU ACM足球賽加權並查集

namespace 如果 main 加權並查集 幫助 iostream sof 報名人數 -- 描述 NKU ACM最近要舉行足球賽,作為此次賽事的負責人,Lee要對報名人員進行分隊。分隊要遵循如下原則: 一個人不能加入多支隊伍;不認識的人不能分在同一隊;如果a和b認識,

CodeForces - 349BColor the Fence 貪心,填數

題幹: Igor has fallen in love with Tanya. Now Igor wants to show his feelings and write a number on the fence opposite to Tanya's house. Igor thinks

CodeForces - 255CAlmost Arithmetical Progression dp,離散化

題幹: Gena loves sequences of numbers. Recently, he has discovered a new type of sequences which he called an almost arithmetical progression. A seq

CodeForces - 244BUndoubtedly Lucky Numbers dfs打表 + 二分

題幹: Polycarpus loves lucky numbers. Everybody knows that lucky numbers are positive integers, whose decimal representation (without leading zeroes

CodeForces - 76DPlus and xor位運算-異或

Bitwise exclusive OR (or bitwise addition modulo two) is a binary operation which is equivalent to applying logical exclusive OR to every pair of bi