幽灵蛛(pholcus)规则(二)

此文档主要涉及到页面解析,goquery的使用方法,我觉得可以专门写篇文档。package pholcus_lib

// 基础包
import (
    "github.com/henrylee2cn/pholcus/common/goquery"                          //DOM解析
    "github.com/henrylee2cn/pholcus/app/downloader/request" //必需
    . "github.com/henrylee2cn/pholcus/app/spider"           //必需
    // . "github.com/henrylee2cn/pholcus/app/spider/common" //选用
    // "github.com/henrylee2cn/pholcus/logs"
    // net包
     "net/http" //设置http.Header
    // "net/url"
    // 编码包
    // "encoding/xml"
    //"encoding/json"
    // 字符串处理包
    //"regexp"
    // "strconv"
        "strings"
    // 其他包
     "fmt"
    // "math"
    // "time"
)

func init() {
    FileTest1.Register()
}

var FileTest1 = &Spider{
    Name:        "meizitu图片下载",//url:http://www.meizitu.com/
    Description: "meizitu图片下载",
    // Pausetime: 300,
    // Keyin:   KEYIN,
    // Limit:        LIMIT,
    EnableCookie: false,
    RuleTree: &RuleTree{
        Root: func(ctx *Context) {
            ctx.AddQueue(&request.Request{
                Url:          "http://www.meizitu.com/",
                Rule:         "meizitu",
                ConnTimeout:  -1,
                DownloaderID: 0, //图片等多媒体文件必须使用0(surfer surf go原生下载器)
            })
            
        },

        Trunk: map[string]*Rule{
            "meizitu":{
                ParseFunc: func(ctx *Context) {
                    query := ctx.GetDom()
                    query.Find("#picture p a").Each(func(i int, s *goquery.Selection) { //其中picture是id,
                    //p是tagname a也是tagname,这里就找到了a,而且是好多个,所以用了each进行循环
                        //s.Find(‘p>a‘).
                        fmt.Println("打印一下")
                        fmt.Println(s.Html())//s对象的内部HTML代码
                        fmt.Println("-----------")
                        url1,_:=s.Attr("href")//s的href属性值
                        fmt.Println(url1)
                        fmt.Println("??????????????")
                        //t:=s.Find(‘a‘).Eq(0)
                        //fmt.Println("A的html",t.Html())
                        if href, ok := s.Attr("href"); ok {
                                ctx.AddQueue(&request.Request{
                                    Url:    href,
                                    Header: http.Header{"Content-Type": []string{"text/html; charset=gbk"}},
                                    Rule:   "图片URL",
                                })
                            }
                        })
                },
            },

            "图片URL": {
                ParseFunc: func(ctx *Context) {
                    query := ctx.GetDom()
                    query.Find("#picture p img").Each(func(i int, s *goquery.Selection) {//同上
                        //s.Find(‘p>a‘).
                        fmt.Println("二级页面开始!打印一下????????????????????????????????????")
                        fmt.Println(s.Html())
                        fmt.Println("-----------")
                        url1,_:=s.Attr("src")
                        fmt.Println(url1)
                        fmt.Println("??????????????")
                        fmt.Println("二级页面结束!")
                        //t:=s.Find(‘a‘).Eq(0)
                        //fmt.Println("A的html",t.Html())
                        if href, ok := s.Attr("src"); ok {
                                ctx.AddQueue(&request.Request{
                                    Url:    href,
                                    Header: http.Header{"Content-Type": []string{"text/html; charset=gbk"}},
                                    Rule:   "图片下载",
                                })
                            }
                        
                        })
                },
            },
            "图片下载": {
                ParseFunc: func(ctx *Context) {
                    fmt.Println("图片链接URL:",ctx.GetUrl())
                    picurl:=ctx.GetUrl()//获取链接值,用于为图片命名,这里可能还会涉及新建文件夹,所以后面还需要想想怎么传参数?????
                    picname:=strings.Replace(picurl,"http://mm.howkuai.com/wp-content/uploads/","",-1)//替换值
                    picname=strings.Replace(picname,"/","-",-1)//替换值
                    ctx.FileOutput(picname) // 等价于ctx.AddFile("baidu")
                },
            },
            
        },
    },
}
				
时间: 2024-09-28 22:02:29

幽灵蛛(pholcus)规则(二)的相关文章

规则二:方案中包含扩展

规则二 方案中包括扩展 留出可扩展空间!设计可扩展方案,实现可扩展程序 内容:提供及时可扩展性的DID方法 场景:所有项目通用,是保证可扩展性的最经济有效的方法(资源和时间) Design(D)设计20倍的容量[这里的容量是指:压力容量等] Implement(I)实施3倍的容量 Deploy(D)部署1.5倍的容量 原因:DID为产品扩展提供了经济.有效.及时的方法 要点:在早期考虑可扩展性可以帮助团队节省时间和金钱.在需求发生大约一个月前实施(写代码),在客户蜂拥而至的几天前部署 这个规则是

:幽灵蛛(pholcus)(三)--header get post学习资料

转载请注明出处:http://www.cnblogs.com/SSSR/p/6349298.html get和post参考:http://ju.outofmemory.cn/entry/96382 登录知乎:https://github.com/DeanThompson/zhihu-go 并发:http://studygolang.com/articles/5658 https://sanwen8.cn/p/5985D5k.html 分布式爬虫:https://www.v2ex.com/t/17

【剑指offer】规则二维数组查找

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 思路:从数组左下角开始判断,如果目标数据大于左下角数字,则列号右移(增加),若目标数字小于左下角数字,则行号上移(减小) public class Solution {     public boolean Find(int target, int [][] array) {         int ro

微信支付二维码native原生支付开发模式一

开发前,商户必须在公众平台后台设置支付回调URL.URL实现的功能:接收用户扫码后微信支付系统回调的productid和openid:URL设置详见回调地址设置. 1.业务流程时序图 图6.8:原生支付接口模式一时序图 业务流程说明: 1)商户后台系统根据微信支付规定格式生成二维码(规则见下文第2节),展示给用户扫码. 2)用户打开微信“扫一扫”扫描二维码,微信客户端将扫码内容发送到微信支付系统. 3)微信支付系统收到客户端请求,发起对商户后台系统支付回调URL的调用.调用请求将带product

yaml语法三大规则

规则一:缩进 yaml使用一个固定的缩进风格表示数据层结构关系,Saltstack需要每个缩进级别由两个空格组成.一定不能使用tab键 规则二:冒号 yaml:  mykey: my_value  每个冒号后面一定要有一个空格(以冒号结尾不需要空格,表示文件路径的模版可以不需要空格) 规则三:短横线 想要表示列表项,使用一个短横杠加一个空格.多个项使用同样的缩进级别作为同一个列表的一部分 my_dictionary: - list_value_one - list_value_two - lis

C++primer学习笔记(二)——Chapter 4

4.1  Fundamentals 1.Basic Concepts (1)操作符分为一元,二元或者三元操作符: (2)复杂的表达式中含有很多操作符时: 规则一:分为不同的级别,级别高的先运行: 规则二:相同级别的操作符有执行顺序的确定: (3)操作符可以改变操作数的类型 一般将级别低的转化成级别高的 (4)重载运算符 相同的运算符在对不同类型的对象进行操作的时候,会有不同的功能: (5)Lvalue和Rvalue 显而易见:Lvalue指的是Left value,Rvalue指的是Right

servlet的url-pattern匹配规则详细描述

一.概述 在利用servlet或Filter进行url请求的匹配时,很关键的一点就是匹配规则,但servlet容器中的匹配规则既不是简单的通配,也不是正则表达式,而是由自己的规则,比较容易混淆.本文来详细举例介绍下.下面的说明都是在tomcat服务器中得到验证的. 先介绍一下匹配的概念,上例子代码.在一个app(如名字为myapp)的web.xml文件中,有如下信息: <servlet> <servlet-name>MyServlet</servlet-name> &l

JavaScript函数调用规则

1. [代码][JavaScript]代码     JavaScript函数调用规则一 (1)全局函数调用:function makeArray( arg1, arg2 ){    return [this , arg1 , arg2 ];}这是一个最常用的定义函数方式.相信学习JavaScript的人对它的调用并不陌生.调用代码如下:makeArray('one', 'two');// => [ window, 'one', 'two' ] 这种方式可以说是全局的函数调用.为什么说是全局的函数

SQL Server 的事务和锁(二)-Range S-S锁

在这篇随笔中,我们的主要关注点在 Key-Range Lock.Key-Range Lock有 S-S.S-U.I-N.X-X几种情况.我们一个一个来说,力求明白.遗憾的是,这里可能会比较冗长,那么死锁分析只好依次顺延了. Range S-S锁的获取规则 MSDN 对 Range 锁的规则有部分描述,但是言简意赅,以下我们会将各种情况分解开来,理清MSDN中涉及的或者未涉及的规则,这些规则适用于SQL Server 2000/2005/2008/2008 R2.关于MSDN的描述,请参见:htt