Analysez les informations de prix bas du chèque-cadeau Amazon avec Web scraping & R avec Python

Comment obtenir un chèque-cadeau Amazon à moindre coût avec Amaoku

Connaissez-vous un site appelé Amaoku? C'est un site sur lequel vous pouvez acheter et vendre des chèques-cadeaux Amazon, et il est échangé à un taux de remise d'environ 5 à 10%.

Comment puis-je acheter un chèque cadeau au meilleur prix possible sur ce site? Par exemple, y a-t-il une tendance à ce que le taux d'actualisation soit bon le mardi et que le taux d'actualisation soit mauvais vers le 25?

Heureusement, Amaoku a rendu public Données de transactions passées. Le contenu de cet article est que ces données de transaction ont été récupérées avec Python + Beautiful Soup et analysées avec R.

Si vous écrivez d'abord la conclusion, ce sera comme suit. --Il n'y a pas de relation entre la valeur nominale et le taux d'actualisation

environnement

Grattage Web

Le code Python utilisé est ci-dessous. En tant que flux,

  1. Obtenez la gamme de pages à gratter
  2. Obtenez des informations de transaction ligne par ligne en utilisant Beautiful Soup
  3. Écrivez les informations dans le fichier csv
  4. Passer à la page suivante
  5. Répétez les étapes 2 à 5 dans la plage obtenue en 1.

est.

amaoku_scraping.py


#! coding: UTF-8

from bs4 import BeautifulSoup
import urllib.request
import time

file = open("C:/Users/user/amaoku_transaction_data.csv", 'w') 

# get last page index
last_index = 0
html = urllib.request.urlopen("https://amaoku.jp/past_gift/index_amazon/")
soup = BeautifulSoup(html, "lxml")
a_s =  soup.find(class_="pager_link").find_all('a')
for a in a_s:
    if a.string.replace(u"\xa0", u" ") == u'dernier "':
        last_index = int(a.get('href').split('/')[-1])

# get auction data from a page 
last_index = 20
page_index = 0
while page_index <= last_index:
    url = 'https://amaoku.jp/past_gift/index_amazon/' + str(page_index)
    html = urllib.request.urlopen(url)
    soup = BeautifulSoup(html, 'lxml') 
    rows = soup.find('table', class_='contacttable').find('tbody').find_all('tr')
    # get sales data from a page
    for row in rows:
        line_elements = []
        # if the row is a header, skip 
        if row.has_attr('class') and ['class'][0] == 'tr_tit':
            continue
        items = row.find_all('td')
        for item in items:
            # if the item is empty, skip
            if item.string == None:
                continue
            # clean the string
            element = item.string.replace(',', '').replace('&nbsp;', '').replace('\xa0', '').replace(u'Cercle', '').replace('%', '')
            line_elements.append(element)
        line = ','.join(line_elements)
        if line == '':
            continue
        file.write(line + '\n')

    print("Page {0} processed".format(page_index))
    time.sleep(1)
    # 20 items per a page
    page_index += 20

file.close()
print("Task completed")

Analyser avec R

Prétraitement

Lisez le fichier avec read.csv et mettez un nom dans chaque colonne. Convertissez les données de date et d'heure dans la classe Date.

uri <- "D:/workspace/amaoku_analyze/amaoku_transaction_data.csv"
dat <- read.csv(uri, header=T, fileEncoding="UTF-8", stringsAsFactors = F)
names(dat) <- c("biddate", "facevalue", "bidprice", "discount", "validdate")
dat$biddate2 <- as.Date(dat$biddate)
dat$validdate2 <- as.Date(dat$validdate)

Pour le moment, --biddate: date et heure d'achat --facevalue: valeur faciale --bidprice: Prix d'achat --discount: taux d'actualisation --valid date: date d'expiration est.

Quand j'ai vérifié la ligne avec NaN etc., il y en avait 170.

sum(!complete.cases(dat))  # 170

Je vais l'effacer.

dat = dat[complete.cases(dat),]

Les données sont de 176899 lignes et 7 colonnes.

> str(dat)

'data.frame':	176899 obs. of  7 variables:
 $ biddate   : chr  "2015/12/20 18:58" "2015/12/20 18:03" "2015/12/20 18:03" "2015/12/20 18:01" ...
 $ facevalue : int  10000 5000 5000 20000 3000 5000 5000 3000 10000 3000 ...
 $ bidprice  : int  9750 4825 4825 19300 2880 4800 4825 2895 9700 2895 ...
 $ discount  : num  97.5 96.5 96.5 96.5 96 96 96.5 96.5 97 96.5 ...
 $ validdate : chr  "2015/12/20" "2016/12/20" "2016/11/20" "2016/12/20" ...
 $ biddate2  : Date, format: "2015-12-20" "2015-12-20" "2015-12-20" ...
 $ validdate2: Date, format: "2015-12-20" "2016-12-20" "2016-11-20" ...

Le taux d'actualisation augmente-t-il à mesure que la valeur nominale augmente?

Plus la valeur nominale est élevée, plus le taux d'actualisation est susceptible d'être élevé. Comment est-ce en fait?

require(ggplot2)
ggplot(dat, aes(facevalue, discount)) + geom_point() + labs(x="Face value [yen]", y="Discount rate [%]")

facevalue_vs_discountrate.png

À première vue, il semble qu'il n'y ait pas une telle tendance. Regardons la pente de la droite de régression.

>summary(lm(discount ~ facevalue, data=dat))

Coefficients:
              Estimate Std. Error  t value Pr(>|t|)    
(Intercept)  9.401e+01  5.586e-03 16828.37   <2e-16 ***
facevalue   -1.812e-05  2.516e-07   -72.03   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

L'inclinaison est-1.812e-05。Pr(>|t|)C'est important quand on regarde la valeur de. En d'autres termesSi la valeur faciale augmente de 1000 yens, le prix sera de 0.02%DescendreIl y a une tendance. C'est presque dans la plage d'erreur.

** Conclusion: il n'y a pas de relation entre la valeur nominale et le taux d'actualisation **

Y a-t-il une relation entre la période de validité et le taux d'actualisation?

D'une manière générale, plus la période de validité est courte, plus la demande est faible, de sorte que le taux d'actualisation est susceptible d'être plus élevé. Et la vérité?

Calculez la période de validité à partir de la date d'expiration et de la date et de l'heure d'achat, et tracez-la avec le taux de remise.

dat$timediff <- as.numeric(difftime(dat$validdate2, dat$biddate2, units = "days")) / 365.24
ggplot(dat, aes(timediff, discount)) + geom_point() +
    labs(x="Valid period [year]", y="Discount [%]")

validperiod_vs_discountrate.png

Il ne semble pas non plus y avoir de tendance particulière ici. La pente de la droite de régression était de -0,099743 (p <2e-16) de la même manière qu'auparavant.

Il semble que le taux d'actualisation soit faible avec une période de validité d'un an, mais c'est probablement parce que le nombre d'échantillons est important et la base de distribution est large. Voici l'histogramme.

** Conclusion: il n'y a pas de relation entre la période de validité et le taux d'actualisation **

ggplot(dat, aes(timediff)) + geom_histogram(binwidth = 1/12) + xlim(-1, 5) +
    labs(x="Valid period [year]", y="Frequency")

validperiod_histogram.png

Comment le taux d'actualisation évolue-t-il tout au long de l'année?

Comment le taux d'actualisation change-t-il lorsqu'il est visualisé tout au long de l'année? Y a-t-il une saison bon marché?

ggplot(dat, aes(biddate2, discount)) + geom_point(size=1) +
    ylim(75, 100) + labs(x="Date", y="Discount [%]")

date_vs_discountrate.png

Les chiffres sur l'axe horizontal correspondent aux mois de 2015. Il montre un mouvement sinueux. Puisque les données acquises cette fois-ci sont pour l'année écoulée, je ne connais pas les détails des fluctuations saisonnières, mais en regardant les données pour toute l'année, cette saison semble coûter cher. En ce qui concerne le graphique, 92,5-95% ressemble à un prix de marché.

** Conclusion: actuellement cher. Attendez qu'il atteigne 92,5-95% avant d'acheter. ** **

Y a-t-il une relation entre le jour et le taux d'actualisation?

Vérifiez également le jour. Le nombre d'utilisateurs du site étant important les samedis et dimanches, ce sera avantageux pour le vendeur et le taux de remise sera pire.

weekdays_names=c("Lundi","Mardi","Mercredi","Jeudi","Vendredi","samedi","dimanche")
dat$weekdays <- factor(weekdays(dat$biddate2), levels= weekdays_names)
wddf <- aggregate(discount ~ weekdays, dat, mean)
gggplot(data=dat, aes(weekdays, discount)) + geom_boxplot() + 
    ylim(75,110) + labs(x="Day of the week", y="Discount rate [%]")

dayoftheweek_vs_discountrate.png

** Conclusion: le taux d'actualisation ne change aucun jour **

Y a-t-il une relation entre la date et le taux d'actualisation?

Puisque le 25 est un jour de paie, le portefeuille de l'utilisateur sera hydraté, et même si les conditions sont un peu mauvaises, il se vendra, de sorte que le taux d'actualisation peut empirer.

dat$days <- factor(format(as.POSIXct(dat$biddate), format="%d"))
ggplot(dat, aes(days, discount)) + geom_boxplot() + 
    ylim(75,100) + labs(x="Day of a month", y="Discount rate [%]")

dayofamonth_vs_discountrate.png

** Conclusion: le taux d'actualisation ne change aucun jour **

Le taux d'actualisation change-t-il en fonction de l'heure de la journée?

N'est-il pas possible que le nombre d'utilisateurs diminuera et que le taux de réduction s'améliorera au milieu de la nuit, tôt le matin et pendant la journée? Examinez-vous.

dat$hours <- factor(format(as.POSIXct(dat$biddate), format="%H"))
ggplot(dat, aes(hours, discount)) + geom_boxplot() +
    ylim(75,100) + labs(x="Hour of a day", y="Discount rate [%]")

hourofaday_vs_discountrate.png

De 23h00 à 8h00 le lendemain matin, le prix est élevé. Ce n'est pas une grande différence, mais si vous visez un prix bas, la journée est un bon choix.

** Conclusion: la journée est légèrement moins chère que les autres horaires **

finalement

Qu'as-tu pensé? Sur la base de ces informations, nous espérons que les utilisateurs pourront acheter des chèques-cadeaux Amazon à bas prix.

Recommended Posts

Analysez les informations de prix bas du chèque-cadeau Amazon avec Web scraping & R avec Python
Grattage WEB avec Python (pour mémo personnel)
[Pour les débutants] Essayez le web scraping avec Python
Web scraping avec Python (cours de l'action)
Analyse de données pour améliorer POG 1 ~ Web scraping avec Python ~
Web scraping débutant avec python
Web scraping avec Python Première étape
J'ai essayé webScraping avec python.
Web scraping pour les débutants en Python (1)
Web scraping pour les débutants en Python (4) -1
Obtenez des informations météorologiques avec Python et le grattage
Obtenez des informations sur la propriété en grattant avec python
Premiers pas avec Python Web Scraping Practice
Site de courses de chevaux Web scraping avec Python
Premiers pas avec Python Web Scraping Practice
Scraping Web facile avec Python et Ruby
Préparation au grattage au python [Saveur chocolat]
Exécutez régulièrement le scraping WEB avec AWS-Lambda + Python + Cron
[Pour les débutants] Web scraping avec Python "Accédez à l'URL de la page pour obtenir le contenu"
Web scraping pour les débutants en Python (1) Version améliorée
Scrapage Web rapide avec Python (tout en prenant en charge le chargement JavaScript)
Les débutants en Python sont bloqués dans leur premier scraping Web
Scraping Web pour débutants avec Python (4) --2 Scraping sur Cloud Shell
Grattage en Python (préparation)
Essayez de gratter avec Python.
Grattage avec Python + PhantomJS
Grattage avec du sélénium [Python]
Scraping avec Python + PyQuery
Scraping RSS avec Python
Essayez d'afficher diverses informations utiles pour le débogage avec python
Analysez les actions avec python et recherchez des phases de trading favorables
Exploration Web, scraping Web, acquisition de caractères et sauvegarde d'image avec python