masalibの日記

システム開発、運用と猫の写真ブログです

【python3】urlからはてなblogのxmlを取得する

masalib.hatenablog.com

前回でentry_idが取得できたのでそれをもとにxmlを取得したいと思う

仕様

パラメータ

  • user_id(自分の場合はmasalib)
  • blog_id(blogのdomainになる、独自ドメインの場合は調べていないのでわからない)
  • target_url(取得したいURL)
  • password(apiキー)
    APIキーは,はてなブログの「詳細設定 > AtomPub」から確認できる。APIキーは共有させるために 入力させる形にしています(パスワードなので見せない形)

動き

  1. パスワードを入力する
  2. URLからentry_idを取得する
  3. blogidとentry_idをもとにXMLを取得するエンドポイントを作成する
  4. エンドポイントにbasic認証のヘッダーをいれて通信する

ソース

https://colab.research.google.com/drive/1bf_siLfn-wA2qnSHC2Pbu8z6bBRhi5TA

import requests
import bs4
import sys
import getpass

blog_id = "masalib.hatenablog.com"

hatena_id = "masalib"
print('passwordを入力してください(英数字)')
password = getpass.getpass()

targeturl = "https://masalib.hatenablog.jp/entry/2016/02/19/014308"

  
def get_collection_xml(hatena_id, blog_id, password,target_id):
    service_doc_uri = "https://blog.hatena.ne.jp/{hatena_id:}/{blog_id:}/atom/entry/{target_id:}".format(hatena_id=hatena_id, blog_id=blog_id,target_id=target_id)
    print(service_doc_uri) 
    res_service_doc = requests.get(url=service_doc_uri, auth=(hatena_id, password))
    if res_service_doc.ok:
        soup_servicedoc_xml = bs4.BeautifulSoup(res_service_doc.content, features="xml")
 
       #collection_uri = soup_servicedoc_xml.collection.get("entry")
        return res_service_doc.content
    return False
  

def get_target_uri_id(targeturl):
    res = requests.get(targeturl)
    res.raise_for_status()
    soup = bs4.BeautifulSoup(res.text, "html.parser")
    elems = soup.select('article')
    strid =  soup.article.get("id")
    strid =  strid.replace( "entry-"  , "")    
    return (strid)
  
target_id = get_target_uri_id(targeturl)
#print(target_id)  
collection_xml = get_collection_xml(hatena_id, blog_id, password,target_id)
print (collection_xml)

実行結果

感想

  • formatで文字列を作る方法を知らなかったで勉強になった
service_doc_uri = "https://blog.hatena.ne.jp/{hatena_id:}/{blog_id:}/atom/entry/{target_id:}".format(hatena_id=hatena_id, blog_id=blog_id,target_id=target_id)
  • basic認証などが簡単にできた。他のapiなどでも使えるので嬉しいポイントだ
  • 普通の入力だと共有できないので「getpass」を使うと共有できるのが嬉しかった
print('passwordを入力してください(英数字)')
password = getpass.getpass()

参考URL

参考URLは記事リストを取得する形だったが本当にこの記事に助けられた。

cartman0.hatenablog.com