用Python的Django架構編寫從Google Adsense中獲得報表的應用

來源:互聯網
上載者:User
我完成了更新我們在 Neutron的即時收入統計。在我花了一周的時間完成並且更新了我們的PHP指令碼之後,我最終認決定開始使用Python進行抓取,這是值得我去花費我的時間和精力的事情。我建立了一個 Django程式,它可以從不同的來源儲存收入統計,我可以用這些去簡曆視圖和用於統計工具的API。

所以在過去的幾天裡,我寫了一個指令碼,它可以登入到其他的網頁並抓取資料,或者,如果這些網頁有 API,可以直接存取 API。我發現了一些事情。

1.requests >httplib2(requests多於httplib2);

2.SOAP很糟糕,但它至少是一個API,Suds使SOAP好一點。我瞭解到SOAP是我說知道的API中,唯一一個完全基於.net開發的。

3.Beautiful Soup是一個很好的求助對象;

4.我確實十分驚訝,這麼多企業能在如此蹩腳的技術中生存下來。

我拯救了 Google Adsense,他們將會擁有最好的API,並且因此成為最簡單的實現。他有著比我預想的要多的挑戰。顯然你無法僅僅插入使用者名稱/密碼或是APIkey去擷取獲得進入API的入口,你必須完成整個Oauth2的握手流程。

不幸的是,我發現文檔不如我希望過得那樣容易查詢。我發現了很多死連結。我認為,在這方面Google的人應該做的更好。例如,在他們的up to date developer docs文檔中,我發現他們指出了broken link to read more about authentication and authorization。(好的,多麼奇怪,我儘快提交了這個問題,這個連結終於開始工作了,我猜你會感謝我。)


所以,這篇部落格將嘗試記錄從Adsense擷取報表到我的Django應用的過程。

為了使用Google的API來訪問Adsense報表,你需要使用Adsense Management API. 這個API只提供OAuth,所以你需要在瀏覽器中至少完成一次認證過程,來擷取你的認證,然後你可以儲存這些認證來進行下一步操作。說實話,我已經聽說過OAuth很多次了,但是直到現在,我在實踐中仍沒有需要來使用它。所以我是邊做邊學,並歡迎大家留言指出我說的不對的地方。

就我所知,Google對於它的各種產品都擁有一個龐大的API。在研究Adsense之前,你需要在Google API 控制台註冊你的應用。我已經成功註冊了我的應用程式。因為我還沒有一個可用的URL地址,我現在暫時使用我的開發URL(localhost:8000)。它運作起來似乎正常。並使用提供的這個連結下載JSON檔案。

還有,當你管理你的APIs的時候,你需要開啟服務選項卡,開啟AdSense Management API選項。否則,當你嘗試發送請求的時候,你會得到一個錯誤訊息“Access Not Configured”。


Google已經建立了一個Python 用戶端庫,你可以輕易的通過pip來安裝這個庫。它還包含一個Django範例項目,這個項目使用這個庫實現OAuth2的握手過程。我想,它是使用Django 1.1編寫的(因為在寫這個項目的時候,Django 1.5才剛剛發布),所以它可能有點過時,但是它可是一個好的開始點。

我的應用程式很簡單。我只需要讀取指定日期的收益金額,並儲存到我的本機資料庫。

我在djaongo項目中建立了一個新的應用,叫做“adsense”。並建立了一個models.py檔案來儲存認證認證。

from django.contrib.auth.models import Userfrom django.db import modelsfrom oauth2client.django_orm import CredentialsField class Credential(models.Model):  id = models.ForeignKey(User, primary_key=True)  credential = CredentialsField() class Revenue(models.Model):  date = models.DateField(unique=True)  revenue = models.DecimalField(max_digits=7, decimal_places=2)   def __unicode__(self):    return '{0} ${1}'.format(self.date, self.revenue)


我把從API控制台下載的JSON檔案放到我的應用程式的檔案夾下面,並建立了一個views.py檔案


import os from django.conf import settingsfrom django.contrib.auth.decorators import login_requiredfrom django.contrib.sites.models import Sitefrom django.http import HttpResponseBadRequest, HttpResponsefrom django.http import HttpResponseRedirectfrom oauth2client import xsrfutilfrom oauth2client.client import flow_from_clientsecretsfrom oauth2client.django_orm import Storage from .models import Credential CLIENT_SECRETS = os.path.join(os.path.dirname(__file__), 'client_secrets.json') FLOW = flow_from_clientsecrets(  CLIENT_SECRETS,  scope='https://www.googleapis.com/auth/adsense.readonly',  redirect_uri='http://{0}/adsense/oauth2callback/'.format(    Site.objects.get_current().domain)) @login_requireddef index(request):  storage = Storage(Credential, 'id', request.user, 'credential')  credential = storage.get()  if credential is None or credential.invalid is True:    FLOW.params['state'] = xsrfutil.generate_token(settings.SECRET_KEY,                            request.user)    authorize_url = FLOW.step1_get_authorize_url()    return HttpResponseRedirect(authorize_url)  else:    return HttpResponse('Already validated.') @login_requireddef auth_return(request):  if not xsrfutil.validate_token(settings.SECRET_KEY,                  request.REQUEST['state'], request.user):    return HttpResponseBadRequest()  credential = FLOW.step2_exchange(request.REQUEST)  storage = Storage(Credential, 'id', request.user, 'credential')  storage.put(credential)  return HttpResponseRedirect("/")

在 urls.py 檔案中我包含了一個連結指向我的應用程式的url檔案

main urls.py: from django.conf.urls import patterns, include, urlfrom django.contrib import admin admin.autodiscover() urlpatterns = patterns(  '',  url(r'^adsense/', include('adsense.urls', namespace='adsense')),   url(r'^admin/doc/', include('django.contrib.admindocs.urls')),  url(r'^admin/', include(admin.site.urls)),)adsense/urls.py: from django.conf.urls import patterns, url urlpatterns = patterns(  'adsense.views',  url(r'^$', 'index', name='index'),  url(r'^oauth2callback/$', 'auth_return', name='auth_return'),)

最後,建立了一個通過給定日期調用API並擷取收益的類。它放在adsense/tasks.py,因為我準備把它當作任務,鉤在 Celery/ RabbitMQ之上。

import datetimeimport httplib2 from apiclient.discovery import buildfrom django.contrib.auth.models import Userfrom oauth2client.django_orm import Storage from .models import Credential, Revenue TODAY = datetime.date.today()YESTERDAY = TODAY - datetime.timedelta(days=1) class Scraper(object):  def get_report(self, start_date=YESTERDAY, end_date=TODAY):    user = User.objects.get(pk=1)    storage = Storage(Credential, 'id', user, 'credential')    credential = storage.get()    if not credential is None or credential.invalid is False:      http = httplib2.Http()      http = credential.authorize(http)      service = build('adsense', 'v1.2', http=http)      reports = service.reports()      report = reports.generate(        startDate=start_date.strftime('%Y-%m-%d'),        endDate=end_date.strftime('%Y-%m-%d'),        dimension='DATE',        metric='EARNINGS',      )      data = report.execute()      for row in data['rows']:        date = row[0]        revenue = row[1]         record = Revenue()        try:          r = Revenue.objects.get(date=date)          pk = r.id        except Revenue.DoesNotExist:          pk = None        record.id = pk        record.date = date        record.revenue = revenue        record.save()

為了讓它能工作起來,我在瀏覽器開啟http://localhost:8000/adsense/。這時候會要求我登入Google帳號。我為我的應用程式授權來訪問Adsense。然後,認證認證就會儲存在我的本機資料庫,然後我可以調用Scraper get_report() 方法。祝賀我吧!。它能順利工作了。

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.