理系学生日記

おまえはいつまで学生気分なのか

CSS セレクタを学ぶなどしてみた

スクレイピングしたいなーと思いまして,スパイダリングとともにスクレイピングも載ってるという噂の spidering hacks を読むなどしてみました. ISBN:978-4873111872:detail ところが,途中まで読んで気づいたのが,この本には Web::Scraper が載っていない.

たぶん,出版時点で Web::Scraper は開発されてなかった

これはもう,web を使いながら自分で覚えていくしかないかなーと,ぼくは Scraper をちょっと勉強することにした.

HTML 中の抜き出したい要素をどうやって指定するかについては,CSS セレクタと XPath があるみたいですね.ぼくは両方とも,概要しか知らんなーと思って,まずは楽そうな CSS セレクタを見てみた! 研修の休み時間とかに必死こいて見てたよー.たぶん,CSS セレクタの最新の仕様はこれかな.working draft だけど.Selectors Level 3 Web::Scraper の使っている HTML::Selector::XPath は CSS2 に対応していて,読んだのはどうも CSS3 になってしまってたんだけど,あんまし違いはなさそうなのでムシする.

Selector ってなんなのかなって思ってたんですが,

Selectors are patterns that match against elements in a tree. << ツリー上の要素とマッチするパターンのこと,て書かれている. HTML も XML もツリーとして考えることができるので,ここでの tree はそういうことなんだろう.

ん,ということは CSS セレクタって

|css| body{ font-family:"arial" ,sans-serif; } ||< こういうヤツか!使ってるじゃん!CSS セレクタっていうのか.

**CSS2 との違い

1.3. Changes from CSS2

This section is non-normative.

The main differences between the selectors in CSS2 and those in Selectors are:

* the list of basic definitions (selector, group of selectors, simple selector, etc.) has been changed; in particular, what was referred to in CSS2 as a simple selector is now called a sequence of simple selectors, and the term "simple selector" is now used for the components of this sequence
* an optional namespace component is now allowed in type element selectors, the universal selector and attribute selectors
* a new combinator has been introduced
* new simple selectors including substring matching attribute selectors, and new pseudo-classes
* new pseudo-elements, and introduction of the "::" convention for pseudo-elements
* the grammar has been rewritten
* profiles to be added to specifications integrating Selectors and defining the set of selectors which is actually supported by each specification
* Selectors are now a CSS3 Module and an independent specification; other specifications can now refer to this document independently of CSS
* the specification now has its own test suite

<< CSS2 からの違いは -基本用語の定義が変わった.特に CSS2 で simple selector と呼ばれてたものが今は sequence of simple selector と呼ばれるようになって,simple selector は sequence of simple selector の構成要素を指すようになった. -名前空間が各種セレクタに許されるようになった -新しいコンビネータが導入 -substring match ができる simple selector とか,新しい pseudo-class も導入された とからしいです! ぼくは CSS2 をあんまし知らないから,違いもよくわからない!!

**リファレンス

リファレンスとしては 2 章を読んだらいい感じですね. http://www.w3.org/TR/css3-selectors/#selectors

**Case sensitivity

ドキュメントを構成する言語によって違うみたいですけど,HTML は case insensitive だ!

**セレクタの文法

単に使う上では,あんまし読まなくてもよかったかもしれない.

http://www.w3.org/TR/css3-selectors/#selector-syntax Selector: Combinator で区切られた 1 つ以上の sequences of simple selectors の列 Sequence of simple selectors: combinator で区切られていない simple selectors の列 Simple selector: 以下のどれか. -type selector -universal selector -attribute selector -class selector -ID selector -content selector -pseudo-class Combinator: '>', '+', '~' と空白

Simple Selector *Type selector Type selector は HTML or XML のタグ(要素)を指定するセレクタみたいですね. namespace とか関わってくるみたいですけど,今のところスクレイピングに使いそうにないので,そのあたりは気にしないことにしました. そうなると,Type selector というエラそうな名前の割に単なるタグの名前になって,意外と大したことはなさそうだ.

|css| html { .. } a { ... } ||<

***Universal Selector どんな要素名とも一致する,ワイルドカードみたいなセレクタですね.

|css| .warning { hoge; } #myid { hoge; } ||< と |css| .warning { hoge; }

myid { hoge; }

||< は同じになる.

***Attribute Selector

|html|

||< の 'class="hatena-body"' の部分にマッチするセレクタみたい. -"[att]" att という属性させ持っていればマッチする -"[att=val]" att という属性が val であればマッチする -"[att~=val]" att に指定されている値が空白で区切られたリストであって,そのうちの一つが val であればマッチする -"[att|=val]" att に指定されている値の部分が val である,あるいは val- で始まればマッチする and 条件みたいなこともできるようで,

|css| span[hello="cleveland"][goodbye="columbus"] ||< ということができる.

***Class selector div.value と div[class=~value] が等しいということを前提にしていて

|css| *.pastoral { color: green; } ||< は |css| [class~="pastoral"] ||< となるような要素に一致することになる. こっちももちろん,and 条件が指定できる.

|css| p.pastoral.marine ||<

このときは,class="pastoral blue aqua marine" にはマッチするけど,class="pastoral blue" には一致しない.

***ID selector HTML でいう id 属性にマッチするセレクタ.

|css| h1#chapter ||< は,id として chapter が指定されている h1 要素にマッチする

***Pseudo-classes

ドキュメントツリー外の情報だとか,Simple selector では表現できないものに対するマッチ能力を与えるために導入.

|css| a:link a.hover html:lang ||<

とかはよく見たりするんですが,下みたいなのもある.なんかキモい!!

|css| tr:nth-child(2n+1) / represents every odd row of an HTML table / ||<

Combinator たぶんスクレイピングやるために一番大事なのは Combinator じゃないかなー. Descendant combinator 名前通り,ドキュメントツリー上で,ある要素の子孫である要素,というような子孫関係を指定できる.Descendant combinator の正体は空白なので,こんな書き方になる.

|css| A B / 先祖として A を持つ全ての子孫 B にマッチ / h1 em div * p / 少なくとも div と p の間に 1 個の他の要素を含むような p にマッチ / div p *[href] ||<

***Child combinator 子孫ではなくて,親子関係を指定できる! 記号は '>'.

|css| body > p / body の子要素である p にマッチ / ||<

***Adjacent sibling combinators 直近の兄弟関係を指定する.左側に出てくる要素の方がドキュメントツリー上では左になる.記号は '+'.

|css| math + p / math 要素と同じレベル (階層) で,直後に現れる p 要素 / ||<

***General sibling combinators 直近でなくてもいい兄弟関係.記号は '~'

|css| h1 ~ pre ||<

***たぶん 必要そうなのは上の知識.他に Selector's specificity とかが定義されてたんだけど,なににつかうのかが分かんない.