brown water

ゲームやアニメの感想とかプログラムとか

TIPSTARで稼いでみる

TIPSTARとは?

競輪の投票、ライブ中継、予想動画等を見たりすることが出来ます。

何だか怪しげなサイトですが、運営はモンストやmixiで有名なミクシィ
少し意外な感じですが安心出来る会社ではあります。

TIPマネーというものを使ってレースに的中すると払戻金が得られ、現金化することが出来ます。

招待してもらい、TIPマネーをゲット

TIPSTARは現在は招待制となっており、招待されないと登録することが出来ないようです。

というわけで、 招待URLからどうぞ!

なお、PCからでは無理で、スマホからでないと駄目なようです。

新規登録をし、電話番号の入力が必要となります。 ショートメールでコードが送られてくるのでそれを入力。

ホーム画面で、右上の¥マークの所のプラスボタンを押すと本人確認が必要となるので、免許証等をアップロード。
数分後に確認完了のお知らせが来ました。

この時点で、お知らせ→通知から、友情ガチャが出来るようになってるはず。
ガチャを回すと、TIPマネーが最低でも500円貰えます。

本人確認完了後、ホーム画面の左下にあるミッションボタンから、チャレンジタブを選択。
達成マークが付いている項目をタップするとボーナスのTIPマネーが貰えます。

この辺はとにかく分かりにくいですね。

レース必勝法?

TIPマネーだけでは現金化出来ず。 これで車券を買い、的中させて払戻金を受けて初めて現金化することが出来ます。

私は競馬はやりますが、競輪はやったことありません。
それで調べたのですが、ガールズ競輪のワイドが当たりやすいそうです。
「自分でベット」タブを押すとレース画面が出ますが、ここにガールズと書いてあるのを探す。
ガールズ競輪は最初の1~2レースだけっぽい?
出場選手が女性ばかりならOK。これを狙います。
当然ですが、100%当たるという保証はありませんのであしからず。

ワイドというのは、2人選び、その2人共が3着までに入れば的中。順番は関係なし。
競馬でも当たりやすい馬券ですね。
ワイドで、1番人気と2番人気の2人を買います。

しかし競馬は15頭前後出走することが多いのに対し、競輪はその半分のようです。
その分当たる確率も高い代わりに配当も低いです。
私もワイドで3レースほどやりましたが、全て1.0倍でした(笑)
そして、3レースとも的中しました。
1.0倍というのは、損をすることはあっても得をすることは絶対にないという。
ここは貰ったTIPマネーで現金化のために当てるだけなので躊躇はいらないですね。

手持ちのTIPマネーが3500円以上になっていると思います。
2~3回のレースに分けて賭けるも良し、1回で全額賭けるも良し。
もちろん、高額配当を狙って3連単等を買うのもアリですね。
車券を買ったら後はレースを見ながら楽しみましょう。

Pythonで画像スクレイピング&ダウンロード

前回の記事で使ったBeautifulSoupを応用して、今回は画像をスクレイピングしたいと思います。
スクレイピングするサイトですが、これも前に書いた記事Bashで画像ダウンロードで使用したサイトにします。

画像URLの取得

クラス名mdMTMWidget01ItemCite01Valueを探してリンク情報を取得します。

import requests
from bs4 import BeautifulSoup

url='https://matome.naver.jp/odai/2149130246521074801'
req = requests.get(url)
soup = BeautifulSoup(req.text, 'html.parser')
feeds = soup.find_all(class_='mdMTMWidget01ItemCite01Value')
for feed in feeds:
    print(feed.a.get('href'))

これでjpg画像のURLを取得出来ることが分かりました。

画像のダウンロード

sleepを使いたいのでインポートしておきます。

from time import sleep

先程のコードを多少変更して追加

count = 0
for feed in feeds:
    img_url = feed.a.get('href')
    img_file = requests.get(img_url)
    save_name = f'./test_{count:03}.jpg'    #保存場所とファイル名
    with open(save_name, 'wb') as f:
        f.write(img_file.content)
    sleep(1)
    count+=1

ダウンロードにはRequestsを使用します。
保存ファイル名を指定してファイルを書き込み、スリープを挟みながら処理していきます。

複数ページ処理については難しくないと思うので割愛。

まとめ

全コード

import requests
from bs4 import BeautifulSoup
from time import sleep

url='https://matome.naver.jp/odai/2149130246521074801'
req = requests.get(url)
soup = BeautifulSoup(req.text, 'html.parser')
feeds = soup.find_all(class_='mdMTMWidget01ItemCite01Value')

count = 0
for feed in feeds:
    img_url = feed.a.get('href')
    img_file = requests.get(img_url)
    save_name = f'./test_{count:03}.jpg'    #保存場所とファイル名
    with open(save_name, 'wb') as f:
        f.write(img_file.content)
    sleep(1)
    count+=1

ここのサイトのソースが簡単な構造になっているというのもあり、比較的楽に画像スクレイピングが出来ました。
最初はファイルのダウンロードが上手くいかなったのですが、調べたらRequestsを使えば出来ることが分かった。
色々使えるライブラリですね。

Beautifulsoupでスクレイピング

BeautifulsoupはHTMLタグを解析して取得してくれるライブラリです。
Pythonから使ってスクレイピングをしたいと思います。
HTTPライブラリのRequestsもインストールしておきます。

インストール

pip install beautifulsoup4
pip install requests

使い方

準備

RequestsでURLレスポンスを取得し、それを使ってBeautifulSoupオブジェクトを作成します。

import requests
from bs4 import BeautifulSoup

url='http://example.com'
res = requests.get(url)
soup = BeautifulSoup(res.text, 'html.parser')

タグ取得

  • ページ内のAタグの先頭のものだけ取得
feed = soup.find('a')
  • 全てのAタグを取得
feeds = soup.find_all('a')
  • 条件を指定して取得
feeds = soup.find_all('a', class_='sample')

Pythonでは「class」は予約後のため、「class_」になるので注意

タグの情報

  • Aタグのhrefを取得
feed = soup.find('a')
print(feed['href'])

または

feed = soup.find('a')
print(feed.get('href'))
  • Aタグで囲まれたテキストを取得
feed = soup.find('a')
print(feed.text)

スクレイピングしてみる

今回はヤフーニュースのトピックのタイトルとリンクの取得を目的とします。 https://news.yahoo.co.jp/topics/top-picks f:id:chaz4:20200202135704j:plain

HTMLソースを解析

ソースを開き、タイトルから追っていくと、liタグのnewsFeed_item_titleクラスが見つかります。
ここの親階層を辿っていくと、newsFeed_itemクラスが1つのニュースのまとまりだと思われます。

全ニュースを取得

全てのnewsFeed_itemクラスを取得

url = 'https://news.yahoo.co.jp/topics/top-picks'
req = requests.get(url)
soup = BeautifulSoup(req.text, 'html.parser')
feeds = soup.find_all('li', class_='newsFeed_item')

タイトルを取得

ループで一つずつ必要な情報を抜き出していきます。

for feed in feeds:
    title = feed.find(class_='newsFeed_item_title')
    if title:
        print(title.text)

1つのニュースの中で、さらにfindを使って今度はnewsFeed_item_titleクラスを探しています。
見つからなかった場合はNoneが返ってくるので判定しながら次に進みます。
textで文字を取得できます。
ここではタイトルのみを抜き出して表示しています。

リンクを取得

Aタグから取得したいところですが、このページではAタグで取得すると範囲が長いため、ゴチャゴチャした長い文字列になってしまいます。
そこで、普通の文字列で取得したいと思います。

正規表現を使いたいのでインポート。

import re

for feed in feeds:
    link = re.search(r'https://news.yahoo.co.jp/pickup/\d+', str(feed))
    if link:
        print(link.group())

文字列として、「https://news.yahoo.co.jp/pickup/数字」を検索しました。
検索で見つかった場合は、groupメソッドに入っています。

まとめ

今までのコードをまとめ、タイトルとリンクをセットで表示します。

import requests
import re
from bs4 import BeautifulSoup

url = 'https://news.yahoo.co.jp/topics/top-picks'
req = requests.get(url)
soup = BeautifulSoup(req.text, 'html.parser')
feeds = soup.find_all('li', class_='newsFeed_item')

for feed in feeds:
    title = feed.find(class_='newsFeed_item_title')
    link = re.search(r'https://news.yahoo.co.jp/pickup/\d+', str(feed))
    if title and link:
        print(title.text,link.group())

これを加工して色々応用出来ると思います。
次回は画像のスクレイピング&ダウンロードをやってみたいと思います。

Bashで画像ダウンロード

スクレイピングして画像をゲット

適当に選んだサイトから画像をダウンロードしてみたいと思います。

【最新】乃木坂46 衛藤美彩の水着グラビア画像集【みさみさ、みさ先輩】 - NAVER まとめ

水着画像ですが、たまたまこのサイトになっただけです。

ソースから画像の場所を探す

このサイトのソースを見て、画像にリンクされている箇所を探します。

どれでもいいので画像のサムネイルをクリックすると元の大きい画像が出てきて、さらにその画像をクリックするとURLが出ると思います。
色々な所からリンクされていたりするので全部がこの方法ではいかないかもしれないが。

とにかく元画像(JPGファイル)のURLを見つけたらサイトのソースでそれを検索。
複数出るけど、Aタグで囲まれている箇所を特定。
そしてAタグを囲んでいるclassを見つける。
というわけで、「mdMTMWidget01ItemCite01Value」でした。
このクラス名がある行からURLを抜き出していきます。


ソースの取得と抽出

wgetでファイルを取得していきます。
O(大文字のオー)のオプションで出力先を標準出力にすると、ソースコードが出力されます。
パイプラインで繋げてgrepを使い、ここから先ほどのクラス名の行を抽出する。

wget https://matome.naver.jp/odai/2149130246521074801 -O- | grep 'class="mdMTMWidget01ItemCite01Value"'

これで必要な行のみを抽出できました。
ここからさらに画像URLを絞り込んでいきます。
先ほどのコマンドにさらにパイプラインで繋げます。

grep -oP 'http.*.jpg'

正規表現を使ってhttpから続くjpgファイルのURLだけを抜き出しました。

ファイルをひとつずつダウンロードしていく

先ほどのコマンドを変数に入れ、その画像URLをひとつずつ配列に入れて、それを繰り返し処理していきます。
wgetのPオプションで保存先を指定。
サーバーの負担を減らすためにsleepで遅延しておきます。

#!/bin/bash

SRC=https://matome.naver.jp/odai/2149130246521074801

declare -a imgs=()

imgs=$(wget $SRC -O- | grep 'class="mdMTMWidget01ItemCite01Value"' | grep -oP 'http.*.jpg')
for file in ${imgs[@]}; do
    wget $file -P ~/Downloads/img
    sleep 1
done

これでとりあえず完成。
wgetの保存先は好きな場所に変えましょう。
=の前後はスペースを空けるとエラーになります。
上記をtest.sh等の名前で保存。

chmod +x test.sh

で実行権を付け、

./test.sh

で実行します。
これでどんどん画像がダウンロードされてきました。


Udemy売れ筋「実践 Python データサイエンス」

次のページも欲しい

サイトには複数ページがあるので、出来れば全てDLしたいのが人情です。
2ページ目へ行くと分かりますが、URLに?page=2というのが付くだけなので、URLをそれに直せばいいだけ。

しかし手動で全部やるのは面倒!
というわけで、自動でやる手がかりを。

総ページ数さえ取得出来れば後はpageを変えながら同じことをするだけ。
このサイトですが、「MdPagination03」というクラスの所に全ページが集まっているようです。
よって、

wget $SRC | grep -B 1 '/MdPagination03' | grep -v '/MdPagination03' | perl -pe 's/.*>(\d+)<\/a>.*/$1/'

で最終ページを取得することができました。
何かスマートにいかず冗長になってしまった。
SRCは先ほど入れておいたやつ。
後はこれを使って、1から最終ページまで繰り返せば良いだけです。

まぁ、目視で最終ページを入力した方が早いかも(笑)


さくらのVPSに挑戦2(プログラム実行編)

前回VPSの環境を整えたので、今回は実行するプログラムを作っていきます。

作るプログラム

PHPで定期的にTwitterのトレンドを取得して、データベースに保存するプログラムです。
TwitterAPIを使うためにアカウント、アクセスキー等を取得する必要がありますが、方法は割愛します。

データベースの作成

今回はtwget_dbというデータベースを作り、twtrendというテーブルを作ってその中にデータを入れていきます。

mysql -u root -p

でログイン

create database twget_db;
grant all on twget_db.* to twuser@localhost identified by 'paSS%888';

↑twuserは適当なユーザー名、byの次の文字列はパスワード設定です。
これで、twuserがtwget_dbにアクセス出来るようになりました。
次にテーブルの作成

use twget_db
create table twtrend (
    name text,
    day datetime
);

トレンドで取得した単語と日時を格納するテーブルです。
一旦exitで抜けて、

mysql -u twuser -p twget_db

でログインします。
先ほど作ったtwuserでログイン出来ました。
後で確認するためにこれは開いたままにしておきます。

PHPの作成

TwistOAuthという、TwitterAPIから取得するために便利なライブラリを用意します。
github.com ダウンロードした中にある、「TwistOAuth.phar」というファイルを使います。

設定用の値は後で使い回すため、config.phpにまとめておきます。
CONSUMER_KEY等はTwitterで取得した値を入れます。
DB_〜は今回設定したデータベース名、ユーザー名、パスワードです。

//config.php
<?php
define('CONSUMER_KEY', 'xxxxx');
define('CONSUMER_SECRET', 'xxxxx');
define('ACCESS_TOKEN', 'xxxxx');
define('ACCESS_TOKEN_SECRET', 'xxxxx');

define('DB_DATABASE', 'twget_db');
define('DB_USERNAME', 'twuser');
define('DB_PASSWORD', 'paSS%888');
define('PDO_DSN', 'mysql:dbhost=localhost;dbname='.DB_DATABASE);
//twtrend.php
<?php
require_once('config.php');
require_once('TwistOAuth.phar');

$connection = new TwistOAuth(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET);

try {
    $db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $params = ['id' => '1110809', 'exclude' => 'hashtags'];
    $tweets = (array) $connection->get('trends/place', $params);
    
    #日時を変換
    $day = date('Y/m/d H:i:s', strtotime($tweets[0]->created_at));
    
    foreach($tweets[0]->trends as $tweet) {
        $stmt = $db->prepare("insert into twtrend (name,day) values (?,?)");
        $stmt->execute([$tweet->name, $day]);
    }
    
} catch (PDOException $e) {
    echo $e->getMessage();
    exit;
}

APIにある「trends/place」を使って取得しています。
id 1110809は日本、exclude hashtagsはハッシュタグを除くという設定です。

syncer.jp ここのページを見ると他にも応用が出来ると思います。

ラブライブ!コラボキャンペーン

PHPからMySQLに接続するPDOに関しては、ドットインストール等を参照して下さい。
今回作成したconfig.php、twtrend.phpと、ライブラリのTwistOAuth.pharを転送ツールでアップロードします。
FileZillaというソフトを使いました。
アップロード先は/var/www/html/の中です。
アップロードしたら、ブラウザからIPアドレスを入力し、
xxx.xxx.xxx.xx/twtrend.php
でアクセスすると起動します。

今回は取得して書き込むだけのため、画面には何も表示されません。 先ほど開いておいたmysqlの画面で、

select * from twtrend;

を実行して内容が表示されれば成功です。
f:id:chaz4:20180212194401j:plain 短時間で何度もPHPを実行すると同じ内容がどんどん追加されていってしまいます。

delete from twtrend;

でテーブルの中身を空にすることが出来ます。

crontabで定期実行

トレンドを一定時間ごとに取得したいので、crontabを使います。
サーバーにログインした状態で、

crontab -e

でファイルを開き、記述していく。

*/10 * * * * /usr/bin/php /var/www/html/twtrend.php

左端が「分」で、今回は10分ごとに実行します。
phpファイルの実行には /usr/bin/php の記述が必要なようで、その後に実行したいファイル名を書いていきます。
保存して抜けた後、

service crond restart

で有効にしておきます。
これで10分ごとに先ほどのプログラムが実行されて、データベースに書き込まれるはずです。

表示用ファイルの作成

ブラウザから見るためのファイルを作っていきます。
単に全件取得してulタグの中に入れていくだけです。
そのままだと見づらいので、cssも設定してみました。

//puttrend.php
<?php
require_once('config.php');

$twdata = '';

try {
    $db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $stmt = $db->query("select * from twtrend");
    $twdata = $stmt->fetchAll(PDO::FETCH_ASSOC);

} catch (PDOException $e) {
    echo $e->getMessage();
    exit;
}
?>

<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="utf-8">
   <title>tw trend</title>
   <link rel="stylesheet" href="tw.css">
</head>
<body>
    <ul>
        <?php
            if($twdata) {
                foreach ($twdata as $tweet) {
                    echo "<li><span class='name'>".$tweet['name']."</span><span class='day'>(".$tweet['day'].")</span></li>";
                }
            }
        ?>
    </ul>
</body>
</html>

f:id:chaz4:20180212194822j:plain

無事にブラウザからも表示することが出来ました!
今回は単にそのまま表示するだけでしたが、SQL文を変えると単語を集計して多い順に並べて表示する等も簡単に出来ます。


Amazon.co.jpアソシエイト