zoukankan      html  css  js  c++  java
  • C#使用CSS选择器抓取页面内容

    最近在查wpf绘图资料时,偶然看到Python使用CSS选择器抓取网页的功能。觉得很强,这里用C#也实现一下。

    先介绍一下CSS选择器

    在 CSS 中,选择器是一种模式,用于选择需要添加样式的元素。

    选择器

    例子

    例子描述

    .class

    .intro

    选择 class="intro" 的所有元素。

    #id

    #firstname

    选择 id="firstname" 的所有元素。

    *

    *

    选择所有元素。

    element

    p

    选择所有 <p> 元素。

    element,element

    div,p

    选择所有 <div> 元素和所有 <p> 元素。

    element element

    div p

    选择 <div> 元素内部的所有 <p> 元素。

    element>element

    div>p

    选择父元素为 <div> 元素的所有 <p> 元素。

    element+element

    div+p

    选择紧接在 <div> 元素之后的所有 <p> 元素。

    [attribute]

    [target]

    选择带有 target 属性所有元素。

    [attribute=value]

    [target=_blank]

    选择 target="_blank" 的所有元素。

    [attribute~=value]

    [title~=flower]

    选择 title 属性包含单词 "flower" 的所有元素。

    [attribute|=value]

    [lang|=en]

    选择 lang 属性值以 "en" 开头的所有元素。

    :link

    a:link

    选择所有未被访问的链接。

    :visited

    a:visited

    选择所有已被访问的链接。

    :active

    a:active

    选择活动链接。

    :hover

    a:hover

    选择鼠标指针位于其上的链接。

    :focus

    input:focus

    选择获得焦点的 input 元素。

    :first-letter

    p:first-letter

    选择每个 <p> 元素的首字母。

    :first-line

    p:first-line

    选择每个 <p> 元素的首行。

    :first-child

    p:first-child

    选择属于父元素的第一个子元素的每个 <p> 元素。

    :before

    p:before

    在每个 <p> 元素的内容之前插入内容。

    :after

    p:after

    在每个 <p> 元素的内容之后插入内容。

    :lang(language)

    p:lang(it)

    选择带有以 "it" 开头的 lang 属性值的每个 <p> 元素。

    element1~element2

    p~ul

    选择前面有 <p> 元素的每个 <ul> 元素。

    [attribute^=value]

    a[src^="https"]

    选择其 src 属性值以 "https" 开头的每个 <a> 元素。

    [attribute$=value]

    a[src$=".pdf"]

    选择其 src 属性以 ".pdf" 结尾的所有 <a> 元素。

    [attribute*=value]

    a[src*="abc"]

    选择其 src 属性中包含 "abc" 子串的每个 <a> 元素。

    :first-of-type

    p:first-of-type

    选择属于其父元素的首个 <p> 元素的每个 <p> 元素。

    :last-of-type

    p:last-of-type

    选择属于其父元素的最后 <p> 元素的每个 <p> 元素。

    :only-of-type

    p:only-of-type

    选择属于其父元素唯一的 <p> 元素的每个 <p> 元素。

    :only-child

    p:only-child

    选择属于其父元素的唯一子元素的每个 <p> 元素。

    :nth-child(n)

    p:nth-child(2)

    选择属于其父元素的第二个子元素的每个 <p> 元素。

    :nth-last-child(n)

    p:nth-last-child(2)

    同上,从最后一个子元素开始计数。

    :nth-of-type(n)

    p:nth-of-type(2)

    选择属于其父元素第二个 <p> 元素的每个 <p> 元素。

    :nth-last-of-type(n)

    p:nth-last-of-type(2)

    同上,但是从最后一个子元素开始计数。

    :last-child

    p:last-child

    选择属于其父元素最后一个子元素每个 <p> 元素。

    :root

    :root

    选择文档的根元素。

    :empty

    p:empty

    选择没有子元素的每个 <p> 元素(包括文本节点)。

    :target

    #news:target

    选择当前活动的 #news 元素。

    :enabled

    input:enabled

    选择每个启用的 <input> 元素。

    :disabled

    input:disabled

    选择每个禁用的 <input> 元素

    :checked

    input:checked

    选择每个被选中的 <input> 元素。

    :not(selector)

    :not(p)

    选择非 <p> 元素的每个元素。

    ::selection

    ::selection

    选择被用户选取的元素部分。

    C#自带的类库里不支持这个操作,所以需要用到三方库。这里用的是AngleSharp,使用Nuget搜索这个包就可以

    这里以抓取https://technet-info.com/Main.aspx为例 

    页面源码如下:

     1 <html xmlns="http://www.w3.org/1999/xhtml">
     2 <head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="description" content="Wandering the number of windows, stayed in the number of hotels, will feel that separation is not wronged, the feelings are used to browse or used to collect, so that the day had a memorable day" /><title>
     3     Welcome To Technet-Info : Personal Gallery
     4 </title><link rel="shortcut icon" type="image/x-icon" href="technet.ico" media="screen" /><link rel="stylesheet" href="Css/MainCss.css" /><link rel="stylesheet" href="Css/screen.css" />
     5     <style>
     6         #footer{
     7             display: flex;
     8             justify-content: center;
     9             align-items: center;
    10             position: fixed;
    11             bottom: 0;
    12             left: 0;
    13             width: 100%;
    14         }
    15     </style>
    16     <script type="text/javascript" src="js/jquery.js"></script>
    17     <script type="text/javascript" src="js/easySlider1.7.js"></script>   
    18     <script type="text/javascript">
    19         $(document).ready(function () {
    20             $("#slider").easySlider({
    21                 auto: true,
    22                 pause:3000,
    23                 continuous: true,
    24                 numeric: true
    25             });
    26         });     
    27     </script>
    28 </head>
    29 <body>
    30     <form method="post" action="./Main.aspx" id="form1">
    31 <div class="aspNetHidden">
    32 <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKLTQyNjI2MTkwNmRkt331eyucv2SBluj0E2d+0haGV4exFHWtGQkZhNBnpHE=" />
    33 </div>
    34 
    35 <div class="aspNetHidden">
    36 
    37     <input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="202EA31B" />
    38 </div>
    39         <div id="main">
    40             <div id="header">
    41                 <div class="musicarea">
    42                     
    43                     <iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=150 height=52 src="http://music.163.com/outchain/player?type=0&id=516657278&auto=1&height=32"></iframe>
    44                 </div>
    45                 <div class="content">
    46                     
    47                     <div class="logo">
    48                         
    49                         <div class="logo_img">
    50                             <div class="logo_img"></div>
    51                         </div>
    52                         
    53                         <div class="logo_txt">
    54                             <div style="height: 50px;">
    55                                 <p></p>
    56                             </div>
    57                             <div style="height: 50px;">
    58                                 <p>我的freetime</p>
    59                             </div>
    60                         </div>
    61                     </div>
    62 
    63 
    64                     
    65                     <div class="menu">
    66                         
    67                 </div>
    68             </div>
    69             
    70             <div id="content">
    71                 
    72                 
    73                 </div>
    74                                
    75                 <div id="cards">
    76                         
    77                     </div>
    78                 <div id="pin">
    79                     
    80                 </div>
    81 
    82             </div>
    83             
    84             <div id="footer">
    85                 <div id="copyright">
    86                     <p style="margin: 3px">
    87                         <a href="http://www.miitbeian.gov.cn/">湘ICP备17816343号</a>
    88                         <span>|</span>
    89                         <span>Copyright © 2016, www.technet-info.com, All rights reserved.</span>
    90                     </p>
    91                     <p><a href="mailto:zhaotianff@163.com">Email:zhaotianff@163.com</a></p>
    92                 </div>
    93             </div>
    94         </div>
    95     </form>
    96 </body>
    97 </html>

     新建一个控制台工程,引用AngleSharp(由于在Main函数中使用了Async,所以需要Visual Studio 2017+,如果低于这个版本,可以把Main函数中的内容封装成一个函数执行,然后移除Main中的Async)

    初始化

                var config = Configuration.Default;          
                var context = BrowsingContext.New(config);           
                var source = Properties.Resources.HTML;
                var document = await context.OpenAsync(req => req.Content(source));

    建立CSS选择器并执行查询 ,查找class = content的节点

                var cssSelector = ".content";
                var cell = document.QuerySelector(cssSelector);

    输出InnerHtml可以看到如下结果

    基本上到这里就可以愉快的使用CSS选择器进行元素选取了。如果需要上面表格中全部CSS选择器的示例,可以下载示例代码

    这里还有一个实用功能,就是浏览器开发者工具提供了复制CSS选择器的功能

    示例代码待上传。。。。

    最后:

    如果需要进行XPath查询,可以参考

    https://www.cnblogs.com/zhaotianff/p/11319871.html

    这篇文章。虽然示例是基于XML的,但HTML基本上也一样。同样也可以使用上面的浏览器工具复制元素的XPath。

    有兴趣了解C#爬虫相关知识的小伙伴,可以参考

    https://github.com/zhaotianff/CSharpCrawler

    再附上一个详细介绍CSS选择器的链接

    https://developer.mozilla.org/zh-CN/docs/Web/CSS/Attribute_selectors

    ≧◔◡◔≦

  • 相关阅读:
    MySQL与SQLServer的语法区别
    Linux系统ELK环境搭建
    springboot_yml配置, 以及 properties 和yml转换示例
    mybatis-plus的 mapper.xml 路径配置问题
    Windows下 启动redis
    Mysql 创建库,删除库 命令,脚本
    mybatis中传入多个参数时,接口调用报错Parameter '*****' not found ...
    构建启动Vue项目
    HyperLedger/Fabric区块连网络-编译启动单节点
    HyperLedger/Fabric区块连网络 死磕fabric
  • 原文地址:https://www.cnblogs.com/zhaotianff/p/11994402.html
Copyright © 2011-2022 走看看