天天看點

Scrapy(三):使用Selector提取資料(一)

Selector對象

從頁面上提取資料的核心是HTTP文本解析,在Python中常用以下子產品進行處理:

BeautifulSoup: 非常流行的HTTP解析庫,API簡潔易用,但解析速度較慢

lxml: 由C語言編寫的lxml解析庫,解析速度快,API相對比較複雜

Scrapy綜合上述兩者優點實作Selector類,基于lxml建構,簡化了API接口,在Scrapy中使用Selector對象提取頁面上的資料,使用時先通過Xpath或Css選擇器中頁面要提取的資料,然後進行提取。下面詳細介紹Selector對象的使用。

1:建立對象

Selector類基于scrapy.selector子產品,建立selector對象時,可将頁面的HTML文檔字元串傳遞給selector構造器方法的text參數

from scrapy.selector import Selector
text = """
<html>
	<body>
		<h1>Hello World</h1>
		<h1>Hello Scrapy</h1>
		<b>Hello Python</b>
		<ul>
			<li>C++</li>
			<li>JAVA</li>
			<li>Python</li>
		</ul>
	</body>
</html>
"""
selector = Selector(text=text)
print(selector)  # <Selector xpath=None data='<html>\n\t<body>\n\t\t<h1>Hello World</h1>\n\t\t'>
           

也可以使用一個Response對象構造Selector對象,将其傳遞給Selector構造器方法的response參數

from scrapy.selector import Selector
from scrapy.http import HtmlResponse

body = """
<html>
	<body>
		<h1>Hello World</h1>
		<h1>Hello Scrapy</h1>
		<b>Hello Python</b>
		<ul>
			<li>C++</li>
			<li>JAVA</li>
			<li>Python</li>
		</ul>
	</body>
</html>
"""
response = HtmlResponse(url="http://www.example.com", body=body, encoding="utf-8")
selector = Selector(response=response)
print(selector)  # <Selector xpath=None data='<html>\n\t<body>\n\t\t<h1>Hello World</h1>\n\t\t'>
           

2:選中資料

調用Selector對象的xpath或者css方法(傳入Xpath或CSS選擇器表達式),可以選中文檔中的一個或多個部分

selector_list = selector.xpath("//h1")
print(selector_list)
# [<Selector xpath='//h1' data='<h1>Hello World</h1>'>, <Selector xpath='//h1' data='<h1>Hello Scrapy</h1>'>]
           

xpath和css方法傳回一個selector_list對象,其中包含每個被選中部分對應的Selector對象,可以使用for語句進行疊代出每一個Selector對象

selector_list = selector.xpath("//h1")
for i in selector_list:
    print(i.xpath("./text()"))
    # [<Selector xpath='./text()' data='Hello World'>]
# [<Selector xpath='./text()' data='Hello Scrapy'>]
           

selector_list對象也有xpath和css方法,調用它們的辦法行為是:以接收到的參數分别調用其中每一個Selector對象的xpath或css對象方法。并将所有結果收集到一個新的selector_list對象傳回給使用者。請看下面的示例:

selector_list = selector.xpath("//h1")
for i in selector_list.xpath("./text()"):
    print(i)
    # <Selector xpath='./text()' data='Hello World'>
# <Selector xpath='./text()' data='Hello Scrapy'>
           
li = selector.xpath("//ul").css("li").xpath("./text()")
print(li)
# [<Selector xpath='./text()' data='C++'>, <Selector xpath='./text()' data='JAVA'>, <Selector xpath='./text()' data='Python'>]
           

3:提取資料

調用Selector或者Selector_list對象的已下方法可将選中的内容提取:

extract()

re()

extract_first()

re_first()

Selector對象的extract方法将傳回選中内容的Unicode字元串

sl = selector.xpath("//h1")
print(sl[0].extract())  # <h1>Hello World</h1>
print(sl[1].extract())  # <h1>Hello Scrapy</h1>
           

與Selector對象的xpath和css方法類似,SelectorList對象的extract方法内部會調用其中每一個Selector對象的extract方法,并将結果集以一個清單的形式傳回給使用者.

sl = selector.xpath(".//li/text()")
print(sl.extract())  # ['C++', 'JAVA', 'Python']
           

SelectorList對象還有一個extract_first方法,該方法傳回其中一個Selector對象調用extract方法的結果,直接取出Unicode字元串而不是清單

sl = selector.xpath(".//b/text()")
print(sl.extract_first())   # Hello Python
           

同樣我們也可以使用re正規表達式的方式擷取選中内容的部分

text = """
<ul>
			<li>C++,<b>價格:99</b></li>
			<li>java,<b>價格:89</b></li>
			<li>python,<b>價格:90</b></li>
		</ul>
"""
selector = Selector(text=text)
sl = selector.xpath(".//li/b/text()").re("\d+")
print(sl)  # ['99', '89', '90']
           

re_first方法同樣傳回第一個Selector對象調用re方法的結果

sl = selector.xpath(".//li/b/text()").re_first("\d+")
print(sl)  # 99
           

繼續閱讀