反応ネイティブのウェブサイト


ウェブの年から来て反応するネイティブは、私に新鮮なスタートのような感じがします.あなたはネイティブの機能へのより良いアクセスを取得し、あなたのアプリケーションに課せられた少ないルールがあります.例えば、あなたはfetch() おもちゃは、任意のウェブサイトを取得します.これが有効にするのはクライアントサイトのウェブクロールです.

なぜ
多分、あなたはサービスからデータを必要とするでしょう、しかし、彼らはAPIを露出しません、あるいは、APIはあなたに必要なすべてのデータを与えません、あるいは、APIは単に悪いです.通常、ターゲットのウェブサイトをクロールし、使用することができますAPIには、サーバーを設定する必要がありますが、あなたのクライアント内のすべてのウェブサイトからすべてのデータにアクセスすることができますときは、時間を節約することができます.
例えば、アマゾンウェブサイトをとってください.あなたは、ページのすべての製品と次のようにロードする方法を表示したいが、あなた自身のデータ構造でそれをしたいので、あなたはそれの周りに独自のUIを構築することができます.

ハウ
  • サーバからHTMLを取得する
  • HTMLから必要なデータを抽出する
  • 我々の使用のためにデータを再成形してください

  • 1サーバからHTMLを得る
    それは簡単な部分です.
    async function loadGraphicCards(page = 1) {
      const searchUrl = `https://www.amazon.de/s/?page=${page}&keywords=graphic+card`;
      const response = await fetch(searchUrl);   // fetch page
    
      const htmlString = await response.text();  // get response text
      ...
    }
    
    検索パターンでURLを取得すると、いくつかの項目でHTMLページが返されます.

    2 HTMLから必要なデータを抽出する
    これは少しトリッキーです.データはHTMLの中にありますが、それは文字列です.
    ナイーブアプローチは、文字列を解析してデータを取得する正規表現を使用することですが、HTMLは正常な文法を持っていないので、動作しません.
    より良い方法はHTMLパーサーとCSSセレクタを使うことです.
    Cheerio これは解決策です.これはHTMLパーサーとJQuerysコア機能の再実装が付属しているので、ノード上で使用することができます.js
    問題は、ネイティブの反応ほとんどのノードが不足しているです.JSパッケージは動作しません.
    私はかなりの時間を探してファインデre-implementation of Cheerio that works on React-Native パッケージの命名は少し奇妙だった.
    しかし、これで、データの抽出は、あまりにもチャイルズ遊びです.
    async function loadGraphicCards(page = 1) {
      const searchUrl = `https://www.amazon.de/s/?page=${page}&keywords=graphic+card`;
      const response = await fetch(searchUrl);      // fetch page 
    
      const htmlString = await response.text();     // get response text
      const $ = cheerio.load(htmlString);           // parse HTML string
    
      const liList = $("#s-results-list-atf > li"); // select result <li>s
      ...
    }
    

    3更なる使用のためにデータを再成形してください
    データがHTMLから抽出された後に、我々は我々のユースケースのためにそれを再構成し始めます.抽出と再整形はここで少しぼやけている<li> 我々が選択したsはマークアップでいっぱいです、そして、彼らからの正しいデータを得ることはあまりにも抽出です、しかし、しばしば、これらの2つのステップは手で手に入ります.
    async function loadGraphicCards(page = 1) {
      const searchUrl = `https://www.amazon.de/s/?page=${page}&keywords=graphic+card`;
      const response = await fetch(searchUrl);  // fetch page 
    
      const htmlString = await response.text(); // get response text
      const $ = cheerio.load(htmlString);       // parse HTML string
    
      return $("#s-results-list-atf > li")             // select result <li>s
        .map((_, li) => ({                      // map to an list of objects
          asin: $(li).data("asin"),                   
          title: $("h2", li).text(),                
          price: $("span.a-color-price", li).text(),
          rating: $("span.a-icon-alt", li).text(),
          imageUrl: $("img.s-access-image").attr("src")
        }));
    }
    
    これは堅牢な例ではありませんが、アイデアを得ると思います.我々は今、Amazonの結果のために独自のUIを作るために我々のアプリのオブジェクトの新しいリストを使用することができます.
    
    class App extends ReactComponent {
      state = {
        page: 0,
        items: [],
      };
    
      componentDidMount = () => this.loadNextPage();
    
      loadNextPage = () =>
        this.setState(async state => {
          const page = state.page + 1;
          const items = await loadGraphicCards(page);
          return {items, page};
        });
    
      render = () => (
        <ScrollView>
          {this.state.items.map(item => <Item {...item} key={item.asin}/>)}
        </ScrollView>
      );
    }
    
    const Item = props => (
      <TouchableOpacity onPress={() => alert("ASIN:" + props.asin)}>
        <Text>{props.title}</Text>
        <Image source={{uri: props.imageUrl}}/>
        <Text>{props.price}</Text>
        <Text>{props.rating}</Text>
      </TouchableOpacity>
    );
    

    結論
    ほとんどの問題と同様に、正しいツールの解決策を簡単になることができます.しばしば、問題はこれらのツールを見つけることについてです:D
    このクライアント側の這っているアプローチはAPIの必要なしで速いプロトタイプを構築するのに用いられることができます.Amazonはとても静かな静的なHTMLを提供するのにとても良いです、それで、それは彼らのサイトでかなりよく働きます.