Очистите URL-адрес видео YouTube от указанного канала c до Json - PullRequest
1 голос
/ 18 июня 2020

Я пытаюсь сохранить URL-адрес, полученный с помощью этого скрипта, в файле json. но я не смог его получить

from bs4 import BeautifulSoup
from lxml import etree
import urllib
import requests
import sys

def fetch_titles(url):
    video_titles = []
    html = requests.get(url)
    soup = BeautifulSoup(html.text, "lxml")
    for entry in soup.find_all("entry"):
        for link in entry.find_all("link"):
            youtube = etree.HTML(urllib.request.urlopen(link["href"]).read()) 
            video_title = youtube.xpath("//span[@id='eow-title']/@title") 
            if len(video_title)>0:
                video_titles.append({"title":video_title[0], "url":link.attrs["href"]})
    return video_titles

def main():
    if sys.argv.__len__() == 1:
        print("Error: You should specifying keyword")
        print("eg: python3 ./main.py KEYWORD")
        return

    url="https://www.youtube.com/feeds/videos.xml?user=LinusTechTips"
    keyword = sys.argv[1]

    video_titles = fetch_titles(url)
    for video in video_titles:
        if video["title"].__contains__(keyword):
            print(video["url"])
            break # add this line, if you want to print the first match only


if __name__ == "__main__":
    main()

мой json файл имеет эту простую структуру

{"url": "https://www.youtube.com/watch?v=xxx"}

Ответы [ 2 ]

1 голос
/ 18 июня 2020

Когда вы печатаете первое совпадение и пропускаете другие, весь main.py будет таким:

from bs4 import BeautifulSoup
from lxml import etree
import urllib
import requests
import sys
import json

def fetch_titles(url):
    video_titles = []
    html = requests.get(url)
    soup = BeautifulSoup(html.text, "lxml")
    for entry in soup.find_all("entry"):
        for link in entry.find_all("link"):
            youtube = etree.HTML(urllib.request.urlopen(link["href"]).read()) 
            video_title = youtube.xpath("//span[@id='eow-title']/@title") 
            if len(video_title)>0:
                video_titles.append({"title":video_title[0], "url":link.attrs["href"]})
    return video_titles

def save_as_json(result, json_file_path):  # I've add this function to save result as json file
    data = json.dumps(result)
    print(data)
    with open(json_file_path, 'w') as file:
          file.write(data)

def main():
    if len(sys.argv) == 1:
        print("Error: You should specifying keyword")
        print("eg: python3 ./main.py KEYWORD")
        return
    json_file_path = "file.json"  # json file path
    url="https://www.youtube.com/feeds/videos.xml?user=LinusTechTips"
    keyword = sys.argv[1]

    video_titles = fetch_titles(url)
    result ={"url": video["url"] for video in list(reversed(video_titles)) if keyword in video['title']}

    save_as_json(result, json_file_path)      

if __name__ == "__main__":
    main()

Знаете что? Я написал код python, который вы упомянули в своем вопросе. Это был ответ на этот вопрос !!

Я заменил foreach l oop на одну строку for и перевернул список, подобный этому list(reversed(video_titles)), на соответствует первому результату.

Удачного кодирования!

1 голос
/ 18 июня 2020

Используйте этот фрагмент кода после вызова fetch_titles(url), импорт, очевидно, должен быть в начале.

import json

# skip

urls = {'url': video['url'] for video in video_titles if keyword in video['title']}
with open('results.json') as f:
    f.write(json.dumps(urls))

Он создает словарь urls, используя понимание dict, за одну операцию. Вызов __contains__ осуществляется через операнд in. Затем он записывает результат в файл результатов. json.

Вы также должны заменить sys.argv.__len__() на len(sys.argv), это правильный, pythoni c способ, как это сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...