18
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

押忍! この世で一匹光通信の営業マンはflaskでwebアプリを完全オーダーしたった! どっこい気合でherokuにdeployしてやった!

Last updated at Posted at 2019-03-04

#はじめに

ゾス! ということでタイトル通り、光通信(元)の血が宿ったエンジニアとして、flaskアプリ制作に挑戦。
エンジニアの皆さんは元ネタがわからないと思うので、下記がわかりやすい社訓社歌。

そして、光通信を思い出すため、光通信によくいる人の独特の喋り方にしながら書いて行きたいと思う。
※「一覧」という言葉がちょくちょく出てくるが、本当は別の言い方である。 
※光通信の人たちに詰められちゃうから、表現をちと変えている。

【営業用語集(光通信に限らず)】
アポ=訪問予約、契約確認状態
アポ掛け、コール=荷電
コミット=git commitではなく、「本日〇〇件契約取ります」っていう宣言の方。大概朝一コミットさせられる。
パーミッション=事前の了承
ゼロアポ=アポイントがゼロ件だったこと or 成績の悪い営業マンの呼び方
コストだから=自分の人件費を伝えられた上で、それを越えてない赤字社員だよってこと。つまりコミットさせられる。
ロープレ=営業マンとお客さんで役割を分けて、営業の練習をすること。これが僕は世界一キライだったと(笑)
500コール=一日の荷電回数。 個人向け営業、法人向け営業で指標は異なる。

早稲田大学卒で無職ニートのFXブログ
http://yumek0.blog61.fc2.com/blog-entry-53.html

光通信を4か月で辞めた話
http://www.ikedahayato.com/20151202/49247312.html

#目次
1,やったこと
2,開発環境
3,コード
4,終わりに

#やったことです、と。
結論、下記を制作しましたよ、と。
作ったら修正が面倒になってURLはテキトーですよ、と。

【アポ練習アプリ】
https://atom-test3.herokuapp.com/

#開発環境です、と。
OS : Mac
言語 : Python 3.6.5
WEBフレームワーク : Flask 0.12
deploy環境 : heroku無料版

#コードです、と。

server.pyです、と。
# -*- coding: utf-8 -*-
from flask import Flask, render_template, request, redirect, url_for , make_response,Response
from flask_cors import CORS, cross_origin
from datetime import datetime
from processing import processing

# flask初期化しちゃいますよ、と。
# アポ掛けもしちゃいますよ、と。
app = Flask(__name__)
CORS(app)

# / にアクセスしたとき、処理しちゃいますよ、と。
@app.route('/')
def index():
    return render_template('index.html')

#/post にアクセスしました、と。 結論、スクレイピングしますよ、と。
@app.route('/post', methods=['GET', 'POST'])
def make_data():
    # POSTの処理をしますよ、と。
    if request.method == 'POST':
        # もしHTTPSが入力されたら下記処理をしますよ、と。
        if "https" in request.form["URL"]:
            URL = request.form['URL']
            # 結論、ここでスクレイピング始めちゃうから。大丈夫エラーなんて出ないから。
            df = processing.first_scray(URL)
            # dataframeがゼロアポじゃなかったら、CSVダウンロードしちゃいますよ、と。
            if len(df):
                return processing.download(df)
    # URLに空白が入力されたら詰められますよ、と。
    shinjin = "新人「光のロマンで迫るからエラーが出ましたゾス」"
    boss = "ボス「いいから早くアポ取ってこいや」"
    return render_template('back.html',shinjin=shinjin, boss=boss)

if __name__ == '__main__':
    # 結論、apo掛けするから。ゼロアポなんて普通にないから。
    # 1日500コール普通だから。500コールでゼロアポなんてないから。
    app.run()

結論、これが全体のルーティングですよ、と。
URLが入力されたら、

server.pyです、と。
df = processing.first_scray(URL)

で処理して、
空白とかフザけたことしたら、詰めますよ、と。
もちろん、テキトーなURL入れたらdataframeが ゼロアポかどうかTrueしちゃうってことで。

server.pyです、と。
if len(df):
   return processing.download(df)

次は、スクレイピング処理を行っているコード  見せちゃうから。
ゼロアポはメモしろよ〜。

processing.pyです、と。
# -*- coding: utf-8 -*-
from flask import make_response
import pandas as pd
from bs4 import BeautifulSoup as bs
import requests

def first_scray(URL):
    # header偽装?? いや、結論、お客さんが喜べば、それイイことだから。
    headers = {
    "User-Agent" : "Mozilla/5.0 (X11; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0",
    }
    # dataframe定義しちゃうから。
    df = pd.DataFrame(index=[] , columns=[])
    # これ多分お客さんからのresponseで受注だから。
    res = requests.get(URL ,headers=headers)
    # ここは落ち着いてhtml見積書解析しちゃいますよ、と。
    soup = bs(res.content, "html.parser")
    try:
        # ここでページ全体のコール一覧取っちゃうから。
        items = soup.select("div.s-item-container")
        # その一覧からfor無限アポ掛けしますよ、と。
        for item in items:
            ## 全国のコール一覧取っちゃうから。
            try:
                title = item.select("img")[0].get("alt")
                item_url = "https://www.amazon.co.jp" + item.select("a")[0].get("href")
                if item.find(class_="a-icon a-icon-jp a-icon-prime-jp a-icon-small s-align-text-bottom"):
                    prime = "prime"
                else:
                    prime = "no prime"
                pic_split = item.select("img")[0].get("srcset").split()
                pic_txt = ",".join(pic_split).split()
                picures_list = []
                for p_txt in pic_txt:
                    if "jpg" in p_txt:
                        picures_list.append(p_txt)
                se = pd.Series(
                    [title, item_url, prime, picures_list],
                    ["title", "item_url", "prime", "picures_list"]
                )
                df = df.append(se, ignore_index=True)
            ## 一覧ないところはスルーして、次行くっしょ。
            except Exception as e:
                pass
    ## 一覧取れないときは、passしちゃうってこと。
    except:
        pass
    ## まとめた一覧に早くアポ掛けしてよ。
    return df

import csv
import io as cStringIO
import random
def download(df):
    # ここに名言ファイル名あるから。
    txt = """
    MoshiMoshiWatakushyyyyy
    NttnohoukaraOdenwashiteorimasu
    Zosu
    Osu
    HikariNoRoman
    KanzenOrderYarimasu
    DokkoiKiaideAgeteYaru
    ShigetaGod
    KonoyodeIppikiHikarXXXXXXXNoEigyomanHa
    """
    txt_split = txt.split()
    # ランダムで名言出ちゃうから。 普通に。
    file_name = random.choice(txt_split)

    # まあ、ここよくわかんないけど、結論大丈夫だから。
    f = cStringIO.StringIO()
    writer = csv.writer(f, quotechar='"', quoting=csv.QUOTE_ALL, lineterminator="\n")
    # ココでカラム名指定してるから。
    writer.writerow(['item_url','pic_list','prime','title'])
    # 一覧上から全部掛けちゃうよ。
    for i in range(len(df)):
        writer.writerow([
            df.item_url[i],
            df.picures_list[i],
            df.prime[i],
            df.title[i]
        ])
    # response作ってるらしいよ。 まあアポ取れればいいでしょ。細かいことは。
    res = make_response()
    res.data = f.getvalue()
    res.headers['Content-Type'] = 'text/csv'
    # ここで名言ファイル名csv出来ちゃいますよ、と。
    res.headers['Content-Disposition'] = 'attachment; filename='+ file_name +'.csv'
    return res

まず、アポで一番大事なパーミッションはここで取るから。
これ普通だから。偽装とかそういう概念とかないから。普通に考えて。
おい メモしろよ! 夜ロープレね。

processing.pyです、と。
headers = {
 "User-Agent" : "Mozilla/5.0 (X11; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0",
}

で、一旦受注します、と。

processing.pyです、と。
# これ多分お客さんからのresponseで受注だから。
res = requests.get(URL ,headers=headers)
# ここは落ち着いてhtml見積書解析しちゃいますよ、と。
soup = bs(res.content, "html.parser")

見積書解析して、それ一覧化しちゃうから。

processing.pyです、と。
# ここでページ全体のコール一覧取っちゃうから。
items = soup.select("div.s-item-container")
# その一覧からfor無限アポ掛けしますよ、と。
for item in items:
  item..... # ここ書くの面倒だからよしなにやっといて

写真の一覧も作って、全部取っちゃうから。
コードの動き??
自分で考えろや。それ脳動いてないから。 だからゼロアポなんだって。結論。

processing.pyです、と。
pic_split = item.select("img")[0].get("srcset").split()
pic_txt = ",".join(pic_split).split()
picures_list = []
for p_txt in pic_txt:
    if "jpg" in p_txt:
        picures_list.append(p_txt)

で、各一覧情報まとめちゃうから。
キミ、今日ゼロアポだったら、pandasライブラリの中身全部写経ね。 手書きノートに。
いやいや、これ皆やってるから。ゼロアポがPC使うとか無いから。

processing.pyです、と。
se = pd.Series(
    [title, item_url, prime, picures_list],
    ["title", "item_url", "prime", "picures_list"]
)
df = df.append(se, ignore_index=True)

Seriesに各一覧情報入れて、それを事前に作ったdataframeに入れるんだって。
これ機械がやってくれるから安心して。

で、一旦コードの説明終了ね。
質問ある??
あ〜、質問できるのゼロアポ以外ね。

一旦質問ない? OKあと細かいところは俺のGitHub見といて。
【GitHub】
https://github.com/LightSign/hikari_roman

ん?? ゼロアポはGitとかいいから。
で、写経いつ終わんの? pandas写経にコミットしろよ。
キミコストだから。

#終わりに
まず、全コードの説明&herokuへのdeployを細かく書こうと思ったが、
結構面倒になったので、ここいらでお暇しようかと(笑)

【この記事に書くにあたっての背景的なヤツ】
僕は約5年半前、中途で光通信に入社し、そこで営業のイロハを学んだ。
そして、約4年前に同期と起業したが、僕は途中で離脱。。。

で、数年さまようよろいになりながらも、
「僕は営業が好きなんだろうか? なんでこんな無駄なアナログな作業な延々しなければならないのか?
こんなことに貴重な時間を割いていていいのだろうか?
プログラミングを覚えてなにか自動化したり、サービスを作るほうが楽しいのでは?
意味わかんねーけどAI作れるかも? ......コミットしたる!」と約2年前に一念発起し、
営業職からデータ分析(SQL、Excelでの基礎集計)に転職をしましたよ、と。

最初はゲーム会社へ派遣され、
派遣先ではExcel Pivot Vlookすらわからず、「SQLめちゃくちゃ書けます!」ってハッタリをかましながら、
光通信で鍛えたパワーをもとに、朝から晩までSQLとExcel習得およびデータ分析にのめり込み、
なんとかコソッと戦力になった。

その後、SQLしか知らない状態だったが、Python=AI最強みたいな説が頭にあったため、
Pythonでスクレイピング等を自己学習。
派遣先の天才エンジニアたちに教えを請いながら、flaskでWEBアプリまで作れるレベルになった。

光通信をネタにしているような書き方をしているが、感謝の意味を込めて今回記事にした。
好きかどうかは置いておいて、光通信は本当にすごい企業だと思っている。
何が凄いかって、売上達成を本当に徹底している。

その精神は僕も引き継いでおり、
「結論、売上立つんだっけ? いつ回収できるんだっけ?」という問いを常に自分にしている。

今はインチキエンジニアとして起業し、活動できている。
僕は非常に運が良かったし、光通信の地獄の入社研修で培った気合でなんとか生きている。

僕の属性は、
営業マン + エンジニア = 魔法剣士
みたいな感じで、どちらもTOPレベルではないが、光通信の営業マンはプログラミングをやらないし、
エンジニアは躊躇なくゴリゴリ商品を売り込むことは苦手だろう。
僕はゴリゴリ売り込むし、SQLもPythonも書けるし、意味はわかってないが、WEBアプリも公開できる。

これが僕の強みであり、引き続きプログラミングスキルをブラッシュアップしていこうと思っている。

また、この世で一匹光通信の営業マンがこの記事を見て、
クスッとしてくれ、リラックスした状態でお客さんのところに行けると嬉しい。
今回の記事を通して、以前の僕のような人間にインチキプログラミングを共有でき、
なにか変化のある行動が生まれたら幸いである。

18
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?