【问题标题】:How to extract text and username from json returned by twitter?如何从twitter返回的json中提取文本和用户名?
【发布时间】:2019-12-19 11:05:08
【问题描述】:

我只想从 Twitter 返回的 JSON 数据中提取用户名和文本。我尝试了 JSON 解析器,但我无法解决。

我正在使用 Twitter 的 HBC API 来检索用户推文。但是,这是返回 JSON 数据。我一直在搜索 Twitter 的 API 以找到一种仅提取推文文本和用户名而不是整个 JSON 的方法,但找不到一个好的解决方案。有人可以帮忙吗?

package abc;
import com.google.common.collect.Lists;
import com.twitter.hbc.ClientBuilder;
import com.twitter.hbc.core.Client;
import com.twitter.hbc.core.Constants;
import com.twitter.hbc.core.Hosts;
import com.twitter.hbc.core.HttpHosts;
import com.twitter.hbc.core.endpoint.StatusesFilterEndpoint;
import com.twitter.hbc.core.processor.StringDelimitedProcessor;
import com.twitter.hbc.httpclient.auth.Authentication;
import com.twitter.hbc.httpclient.auth.OAuth1;
import twitter4j.internal.org.json.JSONException;
import org.apache.kafka.clients.producer.*;
import org.apache.kafka.common.serialization.StringSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

public class TwitterProducer {

    Logger logger = LoggerFactory.getLogger(TwitterProducer.class.getName());

    // use your own credentials - don't share them with anyone
    String consumerKey = "xxxxxxxxxxxxxxxxxxxx";
    String consumerSecret = "xxxxxxxxxxxxxxxxx";
    String token = "xxxxxxxxxxxxxxxxxxxxxxxx";
    String secret = "xxxxxxxxxxxxxxxxxxxxxxx";

    List<String> terms = Lists.newArrayList("india");


    public TwitterProducer(){}

    public static void main(String[] args) throws Exception {
        new TwitterProducer().run();
    }

    public void run() throws Exception{

        logger.info("Setup");

        /** Set up your blocking queues: Be sure to size these properly based on expected TPS of your stream */
        BlockingQueue<String> msgQueue = new LinkedBlockingQueue<String>(1000);

        // create a twitter client
        Client client = createTwitterClient(msgQueue);
        // Attempts to establish a connection.
        client.connect();
       // create a kafka producer
        KafkaProducer<String, String> producer = createKafkaProducer();

        // add a shutdown hook
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            logger.info("stopping application...");
            logger.info("shutting down client from twitter...");
            client.stop();
            logger.info("closing producer...");
            producer.close();
            logger.info("done!");
        }));

        // loop to send tweets to kafka
        // on a different thread, or multiple different threads....
        while (!client.isDone()) {
            String msg = null;
            try {
                msg = msgQueue.poll(5, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
                client.stop();
            }

            if (msg != null){
                logger.info(msg);
                producer.send(new ProducerRecord<>("course5i", null, msg), new Callback() {
                    @Override
                    public void onCompletion(RecordMetadata recordMetadata, Exception e) {
                        if (e != null) {
                            logger.error("Something bad happened", e);
                        }
                    }
                });
            }
        }
        logger.info("End of application");
    }

    public Client createTwitterClient(BlockingQueue<String> msgQueue){

       /** Declare the host you want to connect to, the endpoint, and authentication (basic auth or oauth) */
        Hosts hosebirdHosts = new HttpHosts(Constants.STREAM_HOST);
        StatusesFilterEndpoint hosebirdEndpoint = new StatusesFilterEndpoint();

        hosebirdEndpoint.trackTerms(terms);

        // These secrets should be read from a config file
        Authentication hosebirdAuth = new OAuth1(consumerKey, consumerSecret, token, secret);

        ClientBuilder builder = new ClientBuilder()
                .name("Hosebird-Client-01")                              // optional: mainly for the logs
                .hosts(hosebirdHosts)
                .authentication(hosebirdAuth)
                .endpoint(hosebirdEndpoint)
                .processor(new StringDelimitedProcessor(msgQueue));

               Client hosebirdClient = builder.build();
               return hosebirdClient;
    }

    public KafkaProducer<String, String> createKafkaProducer(){
        String bootstrapServers = "127.0.0.1:9092";

        // create Producer properties
        Properties properties = new Properties();
        properties.setProperty(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
        properties.setProperty(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
        properties.setProperty(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());

        // create safe Producer
        properties.setProperty(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, "true");
        properties.setProperty(ProducerConfig.ACKS_CONFIG, "all");
        properties.setProperty(ProducerConfig.RETRIES_CONFIG, Integer.toString(Integer.MAX_VALUE));
        properties.setProperty(ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION, "5"); // kafka 2.0 >= 1.1 so we can keep this as 5. Use 1 otherwise.

        // high throughput producer (at the expense of a bit of latency and CPU usage)
        properties.setProperty(ProducerConfig.COMPRESSION_TYPE_CONFIG, "snappy");
        properties.setProperty(ProducerConfig.LINGER_MS_CONFIG, "20");
        properties.setProperty(ProducerConfig.BATCH_SIZE_CONFIG, Integer.toString(32*1024)); // 32 KB batch size

        // create the producer
        KafkaProducer<String, String> producer = new KafkaProducer<String, String>(properties);
        return producer;
    }
}

【问题讨论】:

  • 请添加来自 twitter 的 json 响应的样子
  • 我在这里没有看到任何试图解析 json 的代码。你可以再详细一点吗?您在哪里尝试提取“用户名”和“文本”?
  • @BugsForBreakfast{"created_at":"Sun Aug 11 18:02:05 +0000 2019", "id":1160612366238642176, "id_str":"1160612366238642176", "text":"你好你是吗”, “来源”:"\u003ca href=\"https:\/\/mobile.twitter.com\" rel=\"nofollow\"\u003eTwitter Web App\u003c\/a\u003e", "截断":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null, "in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null}
  • @SergeiSirik 我在阻塞队列后在 run() 中尝试过
  • @Arun 好的,您是否将该 json 作为字符串存储在任何变量上?如果不是,请先将其存储在一个变量中,以便我们可以使用它,我不知道您是否只能请求用户名和推文文本,但如果您不能,那么您可以做的是仅从 json 中获取这些属性,你知道怎么做吗?

标签: java json twitter


【解决方案1】:

创建一个属性名称与 json 响应中的属性名称完全相同的类以及 getter/setter。 使用 Jackson ObjectMapper 的 readValue() 函数将这些值映射到该类的对象。

请参阅:https://www.baeldung.com/jackson-object-mapper-tutorial 了解更多信息。

【讨论】:

    【解决方案2】:

    您可以使用任何库中的 JSONObject,但我建议您使用 PrimeFaces,因为它非常简单,因此您需要执行以下操作:

    import org.primefaces.json.JSONObject;
    
    String yourJsonString = msgQueue // Here you need to get your json from that msgQueue and save it as a String, or pass it directly to the argument of following JSONObject
    JSONObject jsonObject = new JSONObject(yourJsonString);
    // After you have the object created you can just access and store the fields you need like so:
    // Im not sure if by username you ment the id but I can't see a field username on the json
    String userName = jsonObject.getString("id");
    String text = jsonObject.getString("text");
    

    应该就是这样,然后你可以使用这些对象来满足你的需要

    【讨论】:

      猜你喜欢
      • 2017-03-14
      • 2013-10-15
      • 2014-02-02
      • 2018-07-05
      • 2016-07-21
      • 1970-01-01
      • 2013-03-26
      • 2011-01-03
      • 2014-07-18
      相关资源
      最近更新 更多