驯服Snoo:使用Reddit API

tech2022-08-20  135

Reddit is a social networking, entertainment, and news website where the content is almost exclusively submitted by users. According to this report, in February 2016 Reddit had 36 million user accounts, 231 million unique monthly visits, and 11.464 active communities. A recent study also showed that 80% of Reddit users get their news from there.

Reddit是一个社交网络,娱乐和新闻网站,其内容几乎完全由用户提交。 根据这份报告 ,截至2016年2月,Reddit拥有3600万用户帐户,每月2.31亿次独立访问和11.464个活跃社区。 最近的一项研究还显示,Reddit用户中有80% 从那里获得新闻 。

Reddit also offers its own API. This way, we can use all the information available on Reddit to enrich our own websites or build our own Reddit clients. In this article, we will tackle some basic Reddit API usage with PHP.

Reddit还提供了自己的API。 这样,我们可以使用Reddit上的所有可用信息来丰富我们自己的网站或构建我们自己的Reddit客户。 在本文中,我们将解决PHP的一些基本Reddit API用法。

Reddit API (The Reddit API)

The Reddit API is extensive and very well documented, from private methods that are only accessible through authentication (Reddit uses OAuth2), to public methods that we can use with a basic HTTP call.

从只能通过身份验证(Reddit使用OAuth2)访问的私有方法,到我们可以与基本HTTP调用一起使用的公共方法, Reddit API的内容广泛且记录充分。

In this article, we’ll first focus on the search method. While this is a public call (it does not require authentication), it is also one of the most powerful ones, since it allows us to access all of the history of Reddit posts in every subreddit.

在本文中,我们将首先关注search方法。 尽管这是一个公共电话(它不需要身份验证),但它也是功能最强大的电话之一,因为它使我们可以访问每个subreddit中Reddit帖子的所有历史记录。

搜索方法 (The search method)

The search method is available through a basic HTTP request and has a lot of properties. Looking at the documentation, we can see that it supports the HTTP GET method and is available through

search方法可通过基本的HTTP请求获得,并具有许多属性。 查看文档 ,我们可以看到它支持HTTP GET方法,并且可以通过以下方式使用

https://www.reddit.com/[/r/subreddit]/search

We also have the following arguments available: after, before, count, include_facets, limit, q, restrict_sr, show, sort, sr_detail, syntax, t, and type. The table below can be found in the documentation, and shows every argument with more detail.

我们还有以下可用参数: after , before , count , include_facets , limit , q , restrict_sr , show , sort , sr_detail , syntax , t和type 。 下表可在文档中找到,并显示每个参数的详细信息。

ArgumentReceivesafterfull name of a thingbeforefull name of a thingcounta positive integer (default: 0)include_facetsboolean valuelimitthe maximum number of items desired (default: 25, maximum: 100)qa string no longer than 512 charactersrestrict_srboolean valueshow(optional) the string allsortone of (relevance, hot, top, new, comments)sr_detail(optional) expand subredditssyntaxone of (cloudsearch, lucene, plain)tone of (hour, day, week, month, year, all)type(optional) comma-delimited list of result types (sr, link) 论据 收到 后 事物的全名 之前 事物的全名 计数 正整数(默认值:0) include_facets 布尔值 限制 所需的最大项目数(默认:25,最大:100) q 不超过512个字符的字符串 strict_sr 布尔值 表演 (可选)字符串all 分类 (相关性,热门,热门,最新,评论)之一 sr_detail (可选)展开subreddits 句法 (cloudsearch,lucene,plain)之一 Ť (小时,日,周,月,年,全部)之一 类型 (可选)以逗号分隔的结果类型列表(sr,链接)

We will focus on the q, limit, sort and restrict_sr arguments.

我们将集中讨论q , limit , sort和restrict_sr参数。

The q argument is the most important one and indicates the query for which we will search the subreddit in question. An example of usage would be:

q参数是最重要的参数,它表示要查询的子reddit的查询。 用法示例如下:

https://www.reddit.com/r/php/search.json?q=oop

This particular call will search for the oop expression in the php subreddit. If you try to make the call using your browser, you will see the results (just copy and paste the link in your browser).

这个特定的调用将在php subreddit中搜索oop表达式。 如果您尝试使用浏览器拨打电话,则会看到结果(只需将链接复制并粘贴到浏览器中)。

The limit argument limits the number of posts that the returned list will have. An example of usage would be:

limit参数限制返回列表将具有的帖子数。 用法示例如下:

https://www.reddit.com/r/php/search.json?q=oop&limit=5

This particular search would return the first 5 results of searching for the oop expression in the php subreddit.

此特定搜索将返回在php subreddit中搜索oop表达式的前5个结果。

The sort argument will sort the searched posts using one of the five Reddit order properties: hot, new, comments, relevance and top. So, if we want to search the php subreddit for newer oop posts we could make the following call:

sort参数将使用五个Reddit订单属性之一对搜索到的帖子进行排序: hot , new , comments , relevance和top 。 因此,如果我们想在php subreddit中搜索较新的oop帖子,则可以进行以下调用:

https://www.reddit.com/r/php/search.json?q=oop&sort=new

The restrict_sr is a boolean value that indicates whether or not we want to restrict our search to the current subreddit. If we pass 0, we will be searching all of Reddit.

restrict_sr是一个布尔值,指示我们是否要限制搜索到当前的subreddit。 如果传递0,我们将搜索所有Reddit。

https://www.reddit.com/r/php/search.json?q=oop&sort=new&restrict_sr=1

All the properties can be combined to make more refined searches.

可以组合所有属性以进行更精确的搜索。

添加PHP (Adding PHP)

Being able to call the API through our browser is fun, but we want something more powerful. We want to be able to parse and use the information we get in a lot of different ways.

能够通过我们的浏览器调用API很有趣,但是我们想要更强大的功能。 我们希望能够以多种不同方式解析和使用我们获得的信息。

For this example on using the Reddit API with PHP we could use cURL, but while having cURL skills can be useful, nowadays it is a rather outdated tool. We will use a library called Guzzle and install it with Composer.

对于将Reddit API与PHP结合使用的示例 ,我们可以使用cURL ,但是拥有cURL技能虽然很有用,但如今它已经过时了。 我们将使用一个名为Guzzle的库并将其与Composer 一起安装。

composer require guzzlehttp/guzzle

For this part of the project, not only will we use Guzzle, we will also use the rest of the arguments we discussed earlier.

对于项目的这一部分,我们不仅将使用Guzzle,还将使用我们先前讨论的其余参数。

<?php namespace ApiReddit; require_once './vendor/autoload.php'; class Searcher { /** * This method queries the reddit API for searches * * @param $subreddit The subreddit to search * @param $query The term to search for * @param $options The filter used to search * @param $results The number of results to return * **/ public function execSearch($subreddit = 'php', $query, $options, $results = 10) { //Executes an http request using guzzle $client = new \GuzzleHttp\Client([ 'headers' => ['User-Agent' => 'testing/1.0'], 'verify' => false]); $response = $client->request("GET", 'https://reddit.com/r/' . $subreddit . '/search.json', ['query' => 'q=' . $query . '&sort=' . $options . '&restrict_sr=1&limit=' . $results ]); $body = $response->getBody(true); return $body; } }

In this search, we added more arguments to further refine our search. Now we have subreddit, options, and results (which is set to 10 by default).

在此搜索中,我们添加了更多参数以进一步优化搜索。 现在我们有了subreddit , options和results (默认设置为10)。

Next we will create an index.php file that will query the Reddit API. We will use Twig to render our view and show the results in a table. Then we will create a /templates folder in the root of our project. This folder will hold our Twig templates.

接下来,我们将创建一个index.php文件,该文件将查询Reddit API。 我们将使用Twig渲染视图并将结果显示在表格中。 然后,我们将在项目的根目录中创建一个/templates文件夹。 该文件夹将保存我们的Twig模板。

composer require twig/twig

The index.php file:

index.php文件:

<?php require __DIR__.'/vendor/autoload.php'; use ApiReddit\Searcher; //Executes a new search $search = new Searcher(); $json=$search->execSearch( 'php', 'composer', 'hot', 5); $data = json_decode($json); //Loads the results in Twig $loader = new Twig_Loader_Filesystem(__DIR__.'/templates'); $twig = new Twig_Environment($loader, array()); //Renders our view echo $twig->render('index.twig', array( 'results' => $data->data->children, ));

After loading Twig, we tell it where we store our templates and to render index.twig.

加载Twig之后,我们告诉它在哪里存储模板并呈现index.twig 。

We also want to create a resources/style.css file to style our results. This file contains the following:

我们还想创建一个resources/style.css文件来设置结果的样式。 该文件包含以下内容:

#posts td, #posts th { border: 1px solid #ddd; text-align: left; padding: 8px; } #posts th { padding-top: 11px; padding-bottom: 11px; background-color: #4CAF50; color: white; }

Finally, we will create our template file keeping in mind both our results and the CSS. Inside the /templates folder, let’s create an index.twig file:

最后,我们将同时考虑结果和CSS来创建模板文件。 在/templates文件夹中,让我们创建一个index.twig文件:

<!DOCTYPE html> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>Reddit Search Table</title> <link rel="stylesheet" type="text/css" href="resources/style.css"> </head> <body> <table id='posts'> <tr> <th>Title</th> <th>Ups</th> <th>Downs</th> <th>Created At</th> <th>Subreddit</th> <th>Number of Comments</th> <th>Link</th> </tr> {% for item in results %} <tr> <td>{{ item.data.title }}</td> <td>{{ item.data.ups }}</td> <td>{{ item.data.downs }}</td> <td>{{ item.data.created_utc }}</td> <td>{{ item.data.subreddits }}</td> <td>{{ item.data.num_comments }}</td> <td>{{ item.data.permalink }}</td> </tr> {% endfor %} </table> </body> </html>

Our final result is here:

我们的最终结果在这里:

添加身份验证 (Adding authentication)

While the search method can be very powerful, the Reddit API has dozens more features we can explore, but most of them require authentication. To be able to access all that functionality, we first need a Reddit account, so please make sure you have one before continuing.

虽然search方法可能非常强大,但是Reddit API具有我们可以探索的更多功能,但是其中大多数功能都需要身份验证。 为了能够使用所有功能,我们首先需要一个Reddit帐户,因此在继续操作之前,请确保您拥有一个帐户。

After we have an account and before we are able to access the API, there’s some configuration work to be done. Log into your account, and in the top right corner you’ll see the “preferences” button. Click it and the go to the “Apps” tab, then click “Create”.

在拥有一个帐户之后,在我们能够访问API之前,需要完成一些配置工作。 登录您的帐户,在右上角,您将看到“首选项”按钮。 单击它,然后转到“应用程序”选项卡,然后单击“创建”。

Fill in the information (and be sure to remember that the Redirect URI will have to be exactly the one we are going to use in our application). We can leave the about url blank.

填写信息(并请记住,重定向URI必须与我们将在应用程序中使用的URI完全相同)。 我们可以将about url留空。

After that, click Create App. This will give us access to a client ID and a secret token. We will be using this information to authenticate via OAuth2 to the API. For the Oauth2 authentication we will use a very well known package, adoy/oauth2. This package is a light PHP wrapper for the OAuth 2.0 protocol (based on OAuth 2.0 Authorization Protocol draft-ietf-oauth-v2-15).

之后,点击Create App 。 这将使我们能够访问客户端ID和秘密令牌。 我们将使用此信息通过OAuth2对API进行身份验证。 对于Oauth2身份验证,我们将使用一个非常知名的软件包adoy/oauth2 。 该软件包是OAuth 2.0协议的轻量级PHP包装器(基于OAuth 2.0授权协议draft-ietf-oauth-v2-15)。

composer require adoy/oauth2

Now that we have the tools for using Oauth2, let’s create a file called Oauth.php in the root of our project with the following content:

现在,我们有了使用Oauth2的工具,让我们在项目的根目录中创建一个名为Oauth.php的文件,其内容如下:

<?php require_once './vendor/autoload.php'; use ApiReddit\Authenticator; $authorizeUrl = 'https://ssl.reddit.com/api/v1/authorize'; $accessTokenUrl = 'https://ssl.reddit.com/api/v1/access_token'; $clientId = 'Your Client Id'; $clientSecret = 'Your Secret'; $userAgent = 'RedditApiClient/0.1 by YourName'; $redirectUrl = "Your redirect url"; $auth = new Authenticator( $authorizeUrl, $accessTokenUrl, $clientId, $clientSecret, $userAgent, $redirectUrl ); $auth->authenticate();

We are creating an instance of Authenticator and calling the authenticate() method. We are also autoloading the class by adding it to Composer. For this to work, let´s create the Authenticator.php class file in our /src folder.

我们正在创建Authenticator的实例,并调用authenticate()方法。 我们还通过将其添加到Composer中来自动加载该类。 为此,我们在/src文件夹中创建Authenticator.php类文件。

<?php namespace ApiReddit; class Authenticator { public function __construct($authorizeUrl, $accessTokenUrl, $clientId, $clientSecret, $userAgent, $redirectUrl) { $this->authorizeUrl = $authorizeUrl; $this->accessTokenUrl = $accessTokenUrl; $this->clientId = $clientId; $this->clientSecret = $clientSecret; $this->userAgent = $userAgent; $this->redirectUrl = $redirectUrl; } public function authenticate() { $client = new \OAuth2\Client($this->clientId, $this->clientSecret, \OAuth2\Client::AUTH_TYPE_AUTHORIZATION_BASIC); $client->setCurlOption(CURLOPT_USERAGENT, $this->userAgent); if (!isset($_GET["code"])) { $authUrl = $client->getAuthenticationUrl($this->authorizeUrl, $this->redirectUrl, array( "scope" => "identity", "state" => "SomeUnguessableValue" )); header("Location: " . $authUrl); die("Redirect"); } else { //$this->getUserPreferences($client, $this->accessTokenUrl); } } }

In the Oauth.php file, we are initializing our project variables with all the data needed to authenticate through the API. Authenticator.php is where the magic happens.

在Oauth.php文件中,我们正在使用通过API进行身份验证所需的所有数据来初始化项目变量。 Authenticator.php是神奇的地方。

We are creating a new OAuth2 client instance with our ID and secret using adoy. After that is basic OAuth logic: we use an authentication URL to execute the authentication and a redirect one to where we will be redirected after authentication.

我们正在使用adoy使用ID和密码创建一个新的OAuth2客户端实例。 之后是基本的OAuth逻辑:我们使用身份验证URL来执行身份验证,然后使用重定向URL重定向到我们在身份验证后将重定向到的位置。

One important thing to notice is the use of a scope in our call. The scope is basically the scope of the functionality we want to have access to. In this case, we are using identity because, in this example, we will be wanting to be fetch our own user information. All the possible actions and respective scopes are explained in the API documentation.

需要注意的重要一件事是在调用中使用scope 。 范围基本上就是我们要访问的功能的范围。 在这种情况下,我们正在使用identity因为在此示例中,我们将希望获取自己的用户信息。 API文档中说明了所有可能的操作和相应的范围。

Last but not least, we have a line that is commented. This was on purpose. The getUserPreferences method will make the call to the API method we want to use. So let’s uncomment that line, and implement the method below.

最后但并非最不重要的一点是,我们有一行被注释。 这是故意的。 getUserPreferences方法将调用我们要使用的API方法。 因此,让我们取消注释该行,并实现以下方法。

/** * This function will request the Reddit API for the user information * * @param $client The client ID * @param $accessToken The access token given */ public function getUserPreferences( $client, $accessToken ) { $params = array("code" => $_GET["code"], "redirect_uri" => $this->redirectUrl); $response = $client->getAccessToken($accessToken, "authorization_code", $params); $accessTokenResult = $response["result"]; $client->setAccessToken($accessTokenResult["access_token"]); $client->setAccessTokenType(OAuth2\Client::ACCESS_TOKEN_BEARER); $response = $client->fetch("https://oauth.reddit.com/api/v1/me.json"); echo('<strong>Response for fetch me.json:</strong><pre>'); print_r($response); echo('</pre>'); }

We are obtaining the access token and using it in our call to fetch information from https://oauth.reddit.com/api/v1/me.json. This GET method will return the identity of the user currently authenticated. The answer will be a json array.

我们正在获取访问令牌,并在调用中使用它来从https://oauth.reddit.com/api/v1/me.json获取信息。 此GET方法将返回当前已验证用户的身份。 答案将是一个json数组。

If we run it, we will be taken to a login page, just like it is supposed to happen with OAuth. After logging in, we will be prompted with this page:

如果我们运行它,我们将被带到登录页面,就像OAuth应该发生的那样。 登录后,将提示您此页面:

Just click allow, and if everything went right, we should have a json array containing all the information about the user we just authenticated with.

只需单击allow,如果一切顺利,我们应该有一个json数组,其中包含我们刚刚通过身份验证的用户的所有信息。

This is how we authenticate with the Reddit API. We can now take a deeper look at the documentation and check all the great things we can make with it.

这就是我们使用Reddit API进行身份验证的方式。 现在,我们可以对文档进行更深入的研究,并检查我们可以利用它完成的所有出色工作。

All the code can be found in this github repository.

所有代码都可以在这个github仓库中找到。

结论 (Conclusion)

We learned how to to use the search functionality of the Reddit API and took a first look at authenticating and using the methods that require a logged in user. But, we just scratched the surface.

我们学习了如何使用Reddit API的搜索功能,并首先了解了认证和使用需要登录用户的方法。 但是,我们只是从头开始。

The possibilities are huge because the Reddit API gives us access to an almost endless knowledge pool. Be sure to check the entire Reddit API documentation as it offers much more, and do let us know if you build anything interesting!

可能性是巨大的,因为Reddit API使我们可以访问几乎无穷无尽的知识库。 请确保查看整个Reddit API文档,因为它提供了更多内容,如果您有任何有趣的东西,请告诉我们!

翻译自: https://www.sitepoint.com/taming-the-snoo-playing-with-the-reddit-api/

相关资源:直到:加入TIL潮流-源码
最新回复(0)