【问题标题】:Create Parser code创建解析器代码
【发布时间】:2023-03-16 19:19:01
【问题描述】:

我对 python 完全陌生,以前从未使用过它。我被困在这个程序上,该程序假设是一个命令行程序,它要求输入关键字,然后在可用标题列表中搜索它们。我使用json将api的信息加载到字典中并且能够搜索它。

我的主要问题是我不知道如何执行 argparser 以使其成为命令行程序。

帮助?

到目前为止,这是我所拥有的代码:

import requests
import argparse
import json
from urllib.request import urlopen


def create_json_file_from_api(url):
    request = urlopen(url)
    data = request.read().decode("utf-8")
    j_data = json.loads(data)
    return j_data


json_data = create_json_file_from_api("http://hn.algolia.com/api/v1/search_by_date?tags=story&numericFilters=created_at_i>1488196800,created_at_i<1488715200")
print(json_data) #making sure the data pulled is correct

def _build_array_of_necessary_data(data, d=[]):
    if 'hits' in data:
        for t in data['hits']:
            d.append({'title' : t.get('title'), 'points': t.get('points'), 'url' : t.get('url')})
            _build_array_of_necessary_data(t,d)
    return d

j = _build_array_of_necessary_data(json_data)
print(j) #testing the function above
def _search_titles_for_keywords(data, word, s=[]):
    for c in data:
        if word in c['title']:
            s.append({'title' : c.get('title')})
    return s

word = "the" #needs to be input by user
word.upper() == word.lower()
k = _search_titles_for_keywords(j, word)
print(k) #testing the function above

def _search_links_for_point_value(data, points, s=[]):
    points = int(points)

    for c in data:
        if points <= c['points']:
            s.append({'Title of article is' : c.get('title')})
    return s

points = "7" #needs to be input by user
l = _search_links_for_point_value(j, points)

print(l)

【问题讨论】:

    标签: python json argparse


    【解决方案1】:

    如果你想把它作为一个带参数的 python 脚本运行,你需要有

    if __name__ == '__main__':
        ...
    

    告诉python运行下面的内容。可以从命令行通过传递带有-w--word 标志的'word' 参数和带有-p--points 标志的'points' 参数来运行以下命令。例子:

    C:\Users\username\Documents\> python jsonparser.py -w xerox -p 2
    or
    C:\Users\username\Documents\> python jsonparser.py --points 3 --word hello
    

    这是重构后的代码:

    import argparse
    from sys import argv
    import json
    from urllib.request import urlopen
    
    
    def create_json_file_from_api(url):
        request = urlopen(url)
        data = request.read().decode("utf-8")
        j_data = json.loads(data)
        return j_data
    
    def _build_array_of_necessary_data(data, d=[]):
        if 'hits' in data:
            for t in data['hits']:
                d.append({'title' : t.get('title'), 'points': t.get('points'), 'url' : t.get('url')})
                _build_array_of_necessary_data(t,d)
        return d
    
    def _search_titles_for_keywords(data, word, s=[]):
        for c in data:
            if word in c['title'].lower():
                s.append({'title' : c.get('title')})
        return s
    
    def _search_links_for_point_value(data, points, s=[]):
        points = int(points)
    
        for c in data:
            if points <= c['points']:
                s.append({'Title of article is' : c.get('title')})
        return s
    
    
    if __name__ == '__main__':
        # create an argument parser, add argument with flags
        parser = argparse.ArgumentParser(description='Search JSON data for `word` and `points`')
        parser.add_argument('-w', '--word', type=str, required=True, 
            help='The keyword to search for in the titles.')
        parser.add_argument('-p', '--points', type=int, required=True, 
            help='The points value to search for in the links.')
        # parse the argument line
        params = parser.parse_args(argv[1:])
    
        url = "http://hn.algolia.com/api/v1/search_by_date?tags=story&numericFilters=created_at_i%3E1488196800,created_at_i%3C1488715200"
        json_data = create_json_file_from_api(url)
        print(json_data[:200]) #making sure the data pulled is correct
    
        j = _build_array_of_necessary_data(json_data)
        print(j) #testing the function above
    
        k = _search_titles_for_keywords(j, params.word.lower())
        print(k) #testing the function above
    
        l = _search_links_for_point_value(j, params.points)
        print(l)
    

    【讨论】:

    • 谢谢你,但我如何获得一个只有与点搜索和关键字匹配的标题的列表?会不会是:for a, b in zip(k, l): print(a,b) 在代码的最后?
    【解决方案2】:

    只需更改您设置点的行以要求用户输入

    points = input("Enter points ")
    

    然后您的程序将向用户询问积分。不过,这没有使用 argparser。当您的脚本因更多输入选项等而变得复杂时,您可以查看 argparser。 https://docs.python.org/3/library/argparse.html

    【讨论】:

    • 我会这样做,但我希望它从命令行运行以使其更易于访问
    【解决方案3】:

    要使用argparse,您首先需要声明ArgumentParser 对象,然后您可以使用add_argument() 方法向该对象添加参数。在此之后,您可以使用parse_args() 方法来解析命令行参数。

    作为使用您的程序的示例:

    import argparse
    
    parser = argparse.ArgumentParser()
    parser.add_argument("word", help="the string to be searched")
    # you will want to set the type to int here as by default argparse parses all of the arguments as strings
    parser.add_argument("point", type = int)
    args = parser.parse_args()
    word = args.word
    point = args.point
    

    在这种情况下,您将按照添加命令的相同顺序从命令行调用它,因此在您的情况下为python your_program.py the 7

    欲了解更多信息,请参阅:https://docs.python.org/3/howto/argparse.html

    【讨论】:

    • 我比我在其他地方遇到的其他解释更了解这一点,但是如何将它作为结合了点和词结果的 main 实例运行?
    猜你喜欢
    • 2012-04-15
    • 1970-01-01
    • 2015-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-04
    相关资源
    最近更新 更多