把setting中的機器人過濾設爲Falsecss
ROBOTSTXT_OBEY = False
artcile
html
選取全部子節點python
/article
程序員
選取根元素 artileshell
article/a
數組
選取全部屬於artile的子元素中的a元素dom
//div
scrapy
選取全部 div 元素(無論出如今文檔任何位置)ide
article//div
函數
選取全部屬於artile元素的後代的 div 元素,無論出如今 article 之下的任何位置
//@class
選取全部名爲 class 的屬性。
/article/div[1]
選取屬於article子元素的第一個div元素
/article/div[last()]
選取屬於article子元素的最後一個div元素
/article/div[last()-1]
選取屬於article子元素的倒數第二個div元素
//div[@lang]
選取全部擁有lang屬性的div元素
//div[@lang='eng']
選取全部lang屬性爲eng的div元素
id是全局惟一的
re_selector2 = response.xpath('//*[@id="post-110595"]/div[1]/h1/text()')
若是class='entry-header'
是全局惟一,能夠比上面少一層節點。
re_selector3 = response.xpath("//div[@class='entry-header']/h1/text()")
對某一頁http://blog.jobbole.com/110595/
進行debug
scrapy shell http://blog.jobbole.com/110595/
獲得response對象。
能夠用dir(response)
看屬性和方法。用type(response)
看類型。
>>> title = response.xpath("//div[@class='entry-header']/h1/text()") >>> title [<Selector xpath="//div[@class='entry-header']/h1/text()" data='爲何該和程序員約會?我有 20 個理由'>]
如何獲取title中的數據?使用extract()
方法,獲得數組,再用序號能夠獲得具體值。
>>> title.extract() ['爲何該和程序員約會?我有 20 個理由'] >>> title.extract()[0] '爲何該和程序員約會?我有 20 個理由'
不直接extra()是由於title 能夠保持爲selector對象。
獲取時間,把裏面的文本用text()
獲取出來。再用strip()
默認出去默認字符。
>>> create_date = response.xpath("//p[@class='entry-meta-hide-on-mobile']/text()").extract()[0] >>> create_date '\r\n\r\n 2017/03/18 · ' >>> create_date = create_date.strip() >>> create_date '2017/03/18 ·' >>> a = create_date.replace("·","").strip() >>> a '2017/03/18' >>> b = create_date.strip("·") >>> b '2017/03/18 ' >>> b = create_date.strip("·").strip() >>> b '2017/03/18'
只取多個class屬性中的一個,用xpath的函數 contains。
好比要選取span
,可是class有多項。而只想要其中的vote-post-up
,能夠用xpath的contains。
<span data-post-id="110595" class=" btn-bluet-bigger href-style vote-post-up register-user-only "><i class="fa fa-thumbs-o-up"></i> <h10 id="110595votetotal">2</h10> 贊</span> >>> response.xpath("//span[contains(@class, 'vote-post-up')]") [<Selector xpath="//span[contains(@class, 'vote-post-up')]" data='<span data-post-id="110595" class=" btn-'>]
列表生成式
過濾評論
>>> response.xpath("//p[@class='entry-meta-hide-on-mobile']/a/text()").extract()[0:] ['其餘', ' 7 評論 ', '約會'] >>> [element for element in tag_list if not element.strip().endswith("評論")] ['其餘', '約會'] tag_list = [ element for element in tag_list if not element.strip().endswith("評論") ] tags = ",".join(tag_list)
以什麼結尾必定是 .endswith()
對數組取第0個、第1個的時候,若是數組爲空,則可能拋出異常。
可是若是用extract_first()
,不用作異常處理,結果爲空或者None。
def extract_first(self, default=None): for x in self: return x.extract() else: return default
相似於字典的get方法,提取不到就返回空。
# -*- coding: utf-8 -*- import re import scrapy class JobboleSpider(scrapy.Spider): name = "jobbole" allowed_domains = ["blog.jobbole.com"] start_urls = ['http://blog.jobbole.com/110595/'] def parse(self, response): # re_selector1 = response.xpath("/html/body/div[1]/div[3]/div[1]/div[1]/h1") # re_selector2 = response.xpath('//*[@id="post-110595"]/div[1]/h1/text()') # re_selector3 = response.xpath("//div[@class='entry-header']/h1/text()") title = response.xpath("//div[@class='entry-header']/h1/text()").extract()[0] create_date = response.xpath("//p[@class='entry-meta-hide-on-mobile']/text()").extract()[0].strip().replace("·","").strip() praise_nums = response.xpath("//span[contains(@class, 'vote-post-up')]//h10/text()").extract()[0] fav_nums = response.xpath("//span[contains(@class, 'bookmark-btn')]/text()").extract()[0] match_re = re.match(".*?(\d+).*", fav_nums) if match_re: fav_nums = match_re.group(1) comment_nums = response.xpath("//a[@href='#article-comment']/span/text()").extract()[0] match_re = re.match(".*?(\d+).*", comment_nums) if match_re: comment_nums = match_re.group(1) content = response.xpath("//div[@class='entry']").extract()[0] tag_list = response.xpath("//p[@class='entry-meta-hide-on-mobile']/a/text()").extract() tag_list = [ element for element in tag_list if not element.strip().endswith("評論") ] tags = ",".join(tag_list) # 經過css選擇器提取字段 title = response.css(".entry-header h1::text").extract()[0] create_date = response.css(".entry-meta-hide-on-mobile::text").extract()[0].strip().replace("·","").strip() praise_nums = response.css("div.post-adds h10::text").extract()[0] # fav_nums = response.css("span[class*='bookmark-btn']::text").extract()[0] fav_nums = response.css(".bookmark-btn::text").extract()[0] match_re = re.match(".*?(\d+).*", fav_nums) if match_re: fav_nums = match_re.group(1) # comment_nums = response.css("span[class='btn-bluet-bigger href-style hide-on-480']::text").extract()[0] comment_nums = response.css("a[href='#article-comment'] span::text").extract_first() match_re = re.match(".*?(\d+).*", comment_nums) if match_re: comment_nums = match_re.group(1) content = response.css(".entry").extract()[0] tag_list = response.css("p.entry-meta-hide-on-mobile a::text").extract() tag_list = [element for element in tag_list if not element.strip().endswith("評論")] tags = ",".join(tag_list) pass