2016-09-20 64 views
0

我正在構建一個使用Scrapy的爬蟲。我需要將字體族分配給特定的HTML元素。(Scrapy)如何獲取HTML元素的CSS規則?

比方說,有一個CSS文件,styles.css中,其中包含以下內容:

p { 
    font-family: "Times New Roman", Georgia, Serif; 
} 

而在HTML頁面中有文字如下:

<p>Hello how are you?</p> 

它很容易對我來說使用Scrapy提取文本,但是我也想知道應用於的字體系列你好,你好嗎?

我希望它只是一個(想象中的XPATH)/p[font-family]或類似的情況。

你知道我該怎麼做嗎?

感謝您的想法。

+0

我個人認爲這不是Scrapy可以處理的東西:(你可能需要看看HTML渲染器的東西。 – starrify

+0

你可以看看https://pythonhosted.org/tinycss/ –

回答

1

你需要單獨下載和解析css。對CSS的解析,您可以使用tinycss甚至正則表達式:

import tinycss 
class MySpider(Spider): 
    name='myspider' 
    start_urls = [ 
     'http://some.url.com' 
    ] 
    css_rules = {} 

def parse(self, response): 
    # find css url and parse it 
    css_url = response.xpath("").extract_first() 
    yield Request(css_url, self.parse_css) 

def parse_css(self, response): 
    parser = tinycss.make_parser() 
    stylesheet = parser.parse_stylesheet(response.body) 
    for rule in stylesheet.rules: 
     if not getattr(rule, 'selector'): 
      continue 
     path = rule.selector.as_css() 
     css = [d.value.as_css() for d in rule.declarations] 
     self.css_rules[path] = css 

現在你有一個CSS路徑和您可以在蜘蛛請求鏈以後使用指定的一些價值觀及其屬性的字典:

def parse_item(self, response): 
    item = {} 
    item['name'] = response.css('div.name').extract_first() 
    name_css = [] 
    for k,v in css_rules.items(): 
     if 'div' in k and '.name' in k: 
      name_css.append(v) 
    item['name_css'] = name_css 
+0

感謝你的回覆。如果頁面有多個CSS文件(例如Bootstrap,Normalize等),並且這些文件(例如)包含多個st文件yling for p elements,你的代碼是否會選擇頁面上p元素使用的實際p CSS樣式,還是會選擇CSS文件中未使用的p CSS樣式?舉例來說,我可以創建許多CSS文件,併爲它們設置多個樣式條目,但由於嵌套或其他一些CSS規則,我的頁面上的HTML可能只使用其中一種樣式。 –

+0

AFAIK html必須指定它正在使用的css,所以你可以選擇它並解析它。即對於堆棧溢出,你可以通過'response.xpath(「// link [@ rel ='stylesheet']/@ href」)找到它''如果它有多個css文件,它會使用多個css文件,所以你需要解析他們所有人都可以自己創建一本詞典或一棵樹。 – Granitosaurus

+0

謝謝。我需要考慮你的解決方案以確保我理解它。我會以任何方式回覆你! –