xpath的語法
xpath語法-謂語
創建Scrapy項目
scrapy startproject ArticleSpider
創建scrapy爬蟲
cd ArticleSpider
scrapy genspiderjobbole blog.jobbole.com
使用方法
可以直接在chrome
->F12
開發者工具中複製xpath
這裏介紹一種測試的方法
平時我們在pycharm或者編輯器需要每次運行,就需要一次次請求,這裏可以用以下的方法:
假設我們需要爬取伯樂在線的一篇文章,鏈接爲 http://blog.jobbole.com/112614/
我們爬取一篇文章的標題
,發佈時間
,點贊數
,收藏數
,評論數
所有字段均以字符串形式存儲
命令行執行如下
scrapy shell http://blog.jobbole.com/112614/
之後,我們可以通過以下命令獲取相應內容,response.xpath()會返回<class 'scrapy.selector.unified.SelectorList'>
類型,可以通過extract()
方法獲取內容,返回列表
In [1]: title = response.xpath('//*[@id="post-112614"]/div[1]/h1/text()')
In [2]: print(title)
[<Selector xpath='//*[@id="post-112614"]/div[1]/h1/text()' data='爲什麼 SQL 正在擊敗 NoSQL,數據的未來是什麼?'>]
In [3]: print(title.extract())
['爲什麼 SQL 正在擊敗 NoSQL,數據的未來是什麼?']
- ####獲取時間
我們再來獲取一下時間,這段比較長,因爲我彙總到了一塊,之前是一點一點調試出來的,過程可見下圖
create_date = response.xpath('//*[@class="entry-meta-hide-on-mobile"]/text()').extract()[0].strip().replace("·","").strip()
strip()是去除頭尾指定的字符
- ####獲取標題
一下代碼是我直接複製的xpath路徑,但在這裏只能提取這一篇文章的數據,因爲可以考到id="post-112614"
,這裏只適用於這一篇文章,其它的就不行了,所以我們需要更換xpath選擇器
create_date = response.xpath('//*[@id="post-112614"]/div[2]/p/text()').extract()[0].strip().repalce("·","").strip()
通過測試,我們發現entry-header
這個class是全局唯一的,於是我們可以這樣提取
title = response.xpath('//*[@class="entry-header"]/h1/text()').extract()[0]
- ####獲取點贊數
praise_nums = response.xpath("//span[contains(@class,'vote-post-up')]/h10/text()").extract()[0]
contains:匹配一個屬性值中包含的字符串
- ####獲取收藏,此處包含’收藏數’和’收藏’兩個字
fav_nums = response.xpath("//span[contains(@class,'bookmark-btn')]/text()").extract()[0].strip()
match_re = re.match('.*(\d+).*',fav_nums)
if match_re:
#獲取收藏數
fav_nums = int(math_re.group(1))
- ####獲取評論
comment_nums = response.xpath('//*[@class="entry-meta-hide-on-mobile"]/a[2]/text()').extract()[0].strip()
- ####獲取文章所屬標籤
在這裏涉及去重,因爲在文章開頭和文末都有評論數,所有會出現重複.如下圖紅色部分,所以我們用判斷去除重複的部分
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('評論')]
tag = ','.join(tag_list)
這個過程如下圖
- ####獲取文章內容
content = response.xpath('//*[@class="entry"]').extract()[0]
完整代碼
def parse_detail(self, response):
#獲取標題
#可以用//*[@id="post-112614"]/div[1]/h1/text()獲取標籤裏面的值
title = response.xpath('//*[@class="entry-header"]/h1/text()').extract()[0]
# print('title',title)
# re1_selector = response.xpath('//div[@class="entry_header"]/h1/text()')
#獲取時間
#獲取字符串的話用time.extract()[0].strip().repalce("·","").strip()
create_date = response.xpath('//*[@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].strip()
match_re = re.match('.*?(\d+).*',fav_nums)
if match_re:
#獲取收藏數
fav_nums = int(match_re.group(1))
else:
fav_nums = 0
#獲取評論數
comment_nums = response.xpath('//*[@class="entry-meta-hide-on-mobile"]/a[2]/text()').extract()[0].strip()
match_re = re.match('.*?(\d+).*', comment_nums)
if match_re:
# 獲取收藏數
comment_nums = int(match_re.group(1))
else:
comment_nums = 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('評論')]
tag = ','.join(tag_list)
content = response.xpath('//*[@class="entry"]').extract()[0]