爬虫介绍

爬虫就是抓取某个或某些Url地址的数据,可供自己使用;如果数据有价值,也可以商用。

就像要把大象装冰箱一样,爬虫一般也有三个步骤:

  1. 抓取Url数据
  2. 解析数据
  3. 使用数据,具体怎么使用看你的需求

要爬取目标网站是:http://quotes.toscrape.com/,该网站是一个国外的网站,专门展示名人名言。简单一点,我们只爬取首页的数据。

首页有十条数据,我们需要爬取每条名言的作者,内容和标签。

添加依赖

爬虫需要用到2个三方库,分别是httphtmlhttp是用来抓取网页数据的,html是用来解析数据的。

pubspec.yaml文件中添加依赖:

dependencies:
  http: 0.12.0+2
  html: ^0.14.0+2

执行下载:

pub get

抓取数据

创建一个crawler.dart文件,编写一个方法getHtml()来抓取数据,代码如下:

import 'package:http/http.dart' as http;

//抓取html
Future<String> getHtml(String url) async{
  var response = await http.get(url);
  return response.body;
}

main() async {
  var url = "http://quotes.toscrape.com/";
  //1.抓取数据
  final html = await getHtml(url);
}

解析数据

解析数据本质是解析html的Dom结构,找到对应的标签,取出文本数据,这里需要你有一些基本的html知识。为了更好的分析目标元素的Dom结构,可以利用Chrome的开发者工具。

编写一个方法parseHtml来解析数据:

import 'package:html/parser.dart' show parse;

//解析html内容
void parseHtml(String html){
  var els = parse(html).querySelectorAll("div.quote");
  els.forEach((el){
    var content = el.querySelector("span.text").innerHtml;//内容
    var author = el.querySelector("span>small.author").innerHtml;//作者
    var tagEls = el.querySelectorAll("div.tags>a");//标签
    tagEls.forEach((el)=> print(el.innerHtml));
  });
}

数据虽然解析出来了,但是这些数据是散乱的,不方便传输,处理以及下一步的使用。我们需要编写一个类来封装这些信息:

class Quote{
  String author, content;
  List<String> tags;
  Quote({this.author, this.content, this.tags});
  String toJson(){
    return """
    {
        "author": $author,
        "content": $content,
        "tags": [${tags.join(", ")}]
    }
    """;
  }
}

改写parseHtml方法如下:

List<Quote> parseHtml(String html){
  var els = parse(html).querySelectorAll("div.quote");
  final list = <Quote>[];
  els.forEach((el){
    var content = el.querySelector("span.text").innerHtml;//内容
    var author = el.querySelector("span>small.author").innerHtml;//作者
    var tagEls = el.querySelectorAll("div.tags>a");//标签
    var tags = <String>[];
    tagEls.forEach((el)=> tags.add(el.innerHtml));
    list.add(Quote(content: content, author: author, tags: tags));
  });
  return list;
}

main方法如下:

main() async {
  var url = "http://quotes.toscrape.com/";
  //1.抓取数据
  final html = await getHtml(url);
  //2.解析数据
  final quotes = parseHtml(html);
}

使用数据

在企业级项目中我们在使用数据之前可能会将数据进行持久化存储,比如保存到Mysql。具体怎么使用,每个公司的需求都不一样,可以用图表展示,数据量大的话可以用大数据框架进行处理。我们这里只是简单的打印Json,编写一个方法printData

//使用数据
void printData(List<Quote> quotes){
  quotes.forEach((q){
    print(q.toJson());
  });
}

最终的main方法如下:

main() async {
  var url = "http://quotes.toscrape.com/";
  //1.抓取数据
  final html = await getHtml(url);
  //2.解析数据
  final quotes = parseHtml(html);
  //3.使用数据,这里仅仅是打印
  printData(quotes);
}

运行项目,将会打印出Json结构的数据:

{
    "author": Albert Einstein,
    "content": “The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”,
    "tags": [change, deep-thoughts, thinking, world]
}
{
    "author": J.K. Rowling,
    "content": “It is our choices, Harry, that show what we truly are, far more than our abilities.”,
    "tags": [abilities, choices]
}
...

通过这个小小的爬虫项目,我们综合练习了类,async/await,三方库添加,集合和高阶函数,原生字符串等知识。

我们目前只爬取了网站首页的数据,如果你对爬虫感兴趣,思考一下,如何能爬取整个网站的数据呢?

更新时间: 5/6/2019, 11:32:40 AM