千家信息网

WebMagic爬虫知识点有哪些

发表于:2025-02-05 作者:千家信息网编辑
千家信息网最后更新 2025年02月05日,这篇文章主要介绍"WebMagic爬虫知识点有哪些",在日常操作中,相信很多人在WebMagic爬虫知识点有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"WebMa
千家信息网最后更新 2025年02月05日WebMagic爬虫知识点有哪些

这篇文章主要介绍"WebMagic爬虫知识点有哪些",在日常操作中,相信很多人在WebMagic爬虫知识点有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"WebMagic爬虫知识点有哪些"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

爬虫架构

WebMagic的四个组件 1.Downloader Downloader负责从互联网上下载页面,以便后续处理。WebMagic默认使用了Apache HttpClient作为下载工具。

2.PageProcessor PageProcessor负责解析页面,抽取有用信息,以及发现新的链接。WebMagic使用Jsoup作为HTML解析工具,并基于其开发了解析XPath的工具Xsoup。

在这四个组件中,PageProcessor对于每个站点每个页面都不一样,是需要使用者定制的部分。

3.Scheduler Scheduler负责管理待抓取的URL,以及一些去重的工作。WebMagic默认提供了JDK的内存队列来管理URL,并用集合来进行去重。也支持使用Redis进行分布式管理。

除非项目有一些特殊的分布式需求,否则无需自己定制Scheduler。

4.Pipeline Pipeline负责抽取结果的处理,包括计算、持久化到文件、数据库等。WebMagic默认提供了"输出到控制台"和"保存到文件"两种结果处理方案。

Pipeline定义了结果保存的方式,如果你要保存到指定数据库,则需要编写对应的Pipeline。对于一类需求一般只需编写一个Pipeline。

代码示例

Webmagic

爬的是虎嗅的文章

pom依赖

                                        us.codecraft                        webmagic-extension                        0.7.3                                                    us.codecraft                    webmagic-core                    0.7.3                

Main

package com.jinguanjia.app.exercise.spider;import us.codecraft.webmagic.Spider;import us.codecraft.webmagic.proxy.Proxy;import us.codecraft.webmagic.proxy.SimpleProxyProvider;/** * @author fengpuchao * @date 2019年7月1日 */public class Main {        public static void main(String[] args){                SimpleHttpClientDownloader httpClientDownloader = new SimpleHttpClientDownloader();                httpClientDownloader.setProxyProvider(                                SimpleProxyProvider.from(new Proxy("101.101.101.101", 8888), new Proxy("102.102.102.102", 8888)));                                    //设置处理器                Spider.create(new HuXiuPageProcessor())                //设置其实url                .addUrl("https://www.huxiu.com")                //处理数据的pipeline                .addPipeline(new DataHandlerPipeline())                //下載器  設置代理//              .setDownloader(httpClientDownloader)                //調度用的,可以處理url//              .setScheduler(scheduler)                // 设置线程数                .thread(5)                .run();                        }}

HuXiuPageProcessor

package com.jinguanjia.app.exercise.spider;import us.codecraft.webmagic.Page;import us.codecraft.webmagic.Site;import us.codecraft.webmagic.Spider;import us.codecraft.webmagic.downloader.HttpClientDownloader;import us.codecraft.webmagic.processor.PageProcessor;import us.codecraft.webmagic.proxy.Proxy;import us.codecraft.webmagic.proxy.SimpleProxyProvider;/** * @author fengpuchao * @date 2019年7月1日 */public class HuXiuPageProcessor implements PageProcessor {                /**         * 设置抓取网站的相关配置         * 重试3次         * 1s中抓取一次         */        private Site site = Site.me().setRetryTimes(3).setSleepTime(1000);                @Override        public Site getSite() {                return site;        }        @Override        public void process(Page page) {                                /**                 * page.getHtml() 提供了很多方法读取内容                 */                                page.addTargetRequests(page.getHtml().links().regex("(https://www.huxiu.com/article/[\\[0-9]+.html)").all());                page.putField("title", page.getHtml().css("div.wrap-left.pull-left > div.article-wrap > h2","text"));                if(page.getResultItems().get("title") == null){                        page.setSkip(true);                }                page.putField("portal", page.getHtml().css("div.wrap-left.pull-left > div.article-wrap > div.article-img-box > img","src"));                page.putField("createTime", page.getHtml().css("div.wrap-left.pull-left > div.article-wrap > div.article-author > div > span.article-time.pull-left","text"));//              page.putField("content", page.getHtml().css("div.article-section-wrap > div.article-section > div.container > div.wrap-left> div.article-wrap > div.article-content-wrap","tidyText"));                page.putField("content", page.getHtml().xpath("//*[@class='article-content-wrap']//tidyText()"));                page.putField("images", page.getHtml().css("img","src").all());        }                        }

DataHandlerPipeline

package com.jinguanjia.app.exercise.spider;import java.util.List;import org.apache.commons.collections.CollectionUtils;import us.codecraft.webmagic.ResultItems;import us.codecraft.webmagic.Task;import us.codecraft.webmagic.pipeline.Pipeline;/** * @author fengpuchao * @date 2019年7月1日 */public class DataHandlerPipeline implements Pipeline {        private int count = 0;        @Override        public void process(ResultItems item, Task task) {                try{                        System.out.println("文章标题:" + item.get("title"));                        System.out.println("文章portal:" + item.get("portal"));                        System.out.println("文章创建时间:" + item.get("createTime"));//                      System.out.println("文章内容:" + item.get("content"));                        System.out.println("第几篇文章:" + count ++ );                        List images = (List)item.get("images");                        if(!CollectionUtils.isEmpty(images)){                                for(String str:images){                                        ImageDownloader.download(str, System.currentTimeMillis()+ ".jpg", "D://images");                                }                        }                }catch(Exception e){                        e.printStackTrace();                }                                        }}

SimpleHttpClientDownloader

package com.jinguanjia.app.exercise.spider;import us.codecraft.webmagic.downloader.HttpClientDownloader;/** * @author fengpuchao * @date 2019年7月1日 */public class SimpleHttpClientDownloader extends HttpClientDownloader {}

ImageDownloader

package com.jinguanjia.app.exercise.spider;import java.io.File;import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;import java.net.URL;import java.net.URLConnection;import com.alibaba.druid.util.StringUtils;/** * @author fengpuchao * @date 2019年7月2日 */public class ImageDownloader {        public static void download(String netUrl, String filename, String savePath) throws Exception {                if (StringUtils.isEmpty(netUrl) || StringUtils.isEmpty(filename) || StringUtils.isEmpty(savePath)) {                        return;                }                URL url = new URL(netUrl);                URLConnection con = url.openConnection();                con.setConnectTimeout(5 * 1000);                try {                        InputStream is = con.getInputStream();                        // 1K的数据缓冲                        byte[] bs = new byte[1024];                        // 读取到的数据长度                        int len;                        // 输出的文件流                        File sf = new File(savePath);                        if (!sf.exists()) {                                sf.mkdirs();                        }                        OutputStream os = new FileOutputStream(sf.getPath() + "\\" + filename);                        try {                                while ((len = is.read(bs)) != -1) {                                        os.write(bs, 0, len);                                }                        } catch (Exception e) {                                e.printStackTrace();                        } finally {                                if (os != null) {                                        os.close();                                }                                if (is != null) {                                        is.close();                                }                        }                } catch (Exception e) {                        e.printStackTrace();                }        }}

Scrapy

创建应用

在开始爬取之前,您必须创建一个新的Scrapy项目。 进入您打算存储代码的目录中,运行下列命令:

scrapy startproject my_spider

该命令将会创建包含下列内容的 tutorial 目录:

my_spider/    scrapy.cfg    my_spider/        __init__.py        items.py        pipelines.py        settings.py        spiders/            __init__.py            ...

这些文件分别是:

  • scrapy.cfg: 项目的配置文件

  • my_spider/: 该项目的python模块。之后您将在此加入代码。

  • my_spider/items.py: 项目中的item文件.

  • my_spider/pipelines.py: 项目中的pipelines文件.

  • my_spider/settings.py: 项目的设置文件.

  • my_spider/spiders/: 放置spider代码的目录.

定义Item

Item 是保存爬取到的数据的容器;其使用方法和python字典类似, 并且提供了额外保护机制来避免拼写错误导致的未定义字段错误。

类似在ORM中做的一样,您可以通过创建一个 scrapy.Item 类, 并且定义类型为 scrapy.Field 的类属性来定义一个Item。 (如果不了解ORM, 不用担心,您会发现这个步骤非常简单)

首先根据需要从dmoz.org获取到的数据对item进行建模。 我们需要从dmoz中获取名字,url,以及网站的描述。 对此,在item中定义相应的字段。编辑 tutorial 目录中的 items.py 文件:

import scrapyclass MySpiderItem(scrapy.Item):    # define the fields for your item here like:    # name = scrapy.Field()    name = scrapy.Field()    title = scrapy.Field()    info = scrapy.Field()

一开始这看起来可能有点复杂,但是通过定义item, 您可以很方便的使用Scrapy的其他方法。而这些方法需要知道您的item的定义。

创建爬虫

在 spiders 目录下创建文件MainSpider.py ,代码内容如下:

# -*- coding: utf-8 -*-import scrapyfrom my_spider.items import MySpiderItemclass MainSpider(scrapy.Spider):    # 用于区分别的Spider,名字必须唯一    name = "itcast"    # 允许搜索的域名范围    allowed_domains = ['itcast.com']    # 启动初始爬取的url    start_urls = {        "http://www.itcast.cn/channel/teacher.shtml",    }    # 是spider的一个方法。 被调用时,每个初始URL完成下载后生成的 Response 对象将会作为唯一的参数传递给该函数。 该方法负责解析返回的数据(response data),提取数据(生成item)以及生成需要进一步处理的URL的 Request 对象    def parse(self,response):        items = []        for each in response.xpath("//div[@class='li_txt']"):            # 将我们得到的数据封装到一个 `ItcastItem` 对象            item = MySpiderItem()            # extract()方法返回的都是unicode字符串            name = each.xpath("h4/text()").extract()            title = each.xpath("h5/text()").extract()            info = each.xpath("p/text()").extract()            # xpath返回的是包含一个元素的列表            item['name'] = name[0]            item['title'] = title[0]            item['info'] = info[0]            items.append(item)        # 直接返回最后数据        return items

settings.py文件设置utf-8编码

ROBOTSTXT_OBEY = False

在 my_spider目录下运行爬虫,输出到 teachers.json 文件中

scrapy crawl itcast -o teachers.json

到此,关于"WebMagic爬虫知识点有哪些"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0