Scrapy網路爬蟲系列教程(二)| 提取網頁上的內容
今天我們新建第一個爬蟲程式,爬取[伯樂線上]網站上一個網頁的內容。
建立專案
[按照上一篇文章所講的,你已經建好一個虛擬環境並安裝好了 scrapy
]
首先,開啟控制檯,進入虛擬環境,輸入 scrapy startproject jobbole
新建一個名字為 jobbole
的專案。
輸入 tree/F jobbole
檢視檔案下的目錄結構。
│ scrapy.cfg
│
└─jobbole
│ items.py
│ middlewares.py
│ pipelines.py
│ settings.py
│ __init__.py
│
├─spiders
│ │ __init__.py
│ │
│ └─__pycache__
└─__pycache__
用 PyCharm
開啟該資料夾,並在 spider
資料夾下新建一個 Python File
檔案,取名為 jobbole_spider
。
在編寫程式之前,我們先分析一下所要抓取的網頁,登入伯樂線上網站,隨便開啟一篇文章:http://python.jobbole.com/89004/
我們要提取這個網頁的標題,釋出時間,標籤,評論數,點贊數等等。
提取資料
學習如何使用 Scrapy
提取資料的最好方法是嘗試使用 Scrapy shell
在控制檯輸入
scrapy shell "http://python.jobbole.com/89004/"
會看到:
2018-02-11 14:10:26 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://python.jobbole.com/89004/> (referer: None)
[s] Available Scrapy objects:
[s] scrapy scrapy module (contains scrapy.Request, scrapy.Selector, etc)
[s] crawler <scrapy.crawler.Crawler object at 0x0000016D64CD9A90 >
[s] item {}
[s] request <GET http://python.jobbole.com/89004/>
[s] response <200 http://python.jobbole.com/89004/>
[s] settings <scrapy.settings.Settings object at 0x0000016D64CD9B70>
[s] spider <DefaultSpider 'default' at 0x16d64f822b0>
[s] Useful shortcuts:
[s] fetch(url[, redirect=True]) Fetch URL and update local objects (by default, redirects are followed)
[s] fetch(req) Fetch a scrapy.Request and update local objects
[s] shelp() Shell help (print this help)
[s] view(response) View response in a browser
>>>
下面用響應物件使用 CSS
選擇元素:
提取標題,輸入:response.css(".type-post h1::text").extract_first()
>>> response.css(".type-post h1::text").extract_first()
'15 分鐘用 ML 破解一個驗證碼系統'
提取建立時間,輸入:response.css(".entry-meta-hide-on-mobile::text").extract_first().strip()[:-2]
>>> response.css(".entry-meta-hide-on-mobile::text").extract_first()
'\r\n\r\n 2018/01/29 · '
>>> response.css(".entry-meta-hide-on-mobile::text").extract_first().strip()
'2018/01/29 ·'
>>> response.css(".entry-meta-hide-on-mobile::text").extract_first().strip()[:-2]
'2018/01/29'
提取標籤,輸入:response.css(".entry-meta a::text").extract()
>>> response.css(".entry-meta a::text").extract()
['實踐專案', ' 1 評論 ', 'OpenCV', 'tensorflow', '機器學習']
提取點贊數,輸入:response.css(".vote-post-up h10::text").extract_first()
>>> response.css(".vote-post-up h10::text").extract_first()
'5'
提取收藏數,輸入:response.css(".bookmark-btn::text").extract_first()
>>> response.css(".bookmark-btn::text").extract_first()
' 12 收藏'
提取評論數,輸入response.css(".hide-on-480::text").extract()[-1]
>>> response.css(".hide-on-480::text").extract()[-1]
' 1 評論'
這裡需要說明的是,呼叫
.extract()
返回的是一個列表,而當你想返回列表中的第一個值,可以呼叫extract_first()
。
除了使用extract()
和extract_first()
方法之外,還可以使用re()
正則表示式進行提取頁面資訊。比如,對於收藏數和評論數,我們僅僅是想提取數字而已,所以得把上面抓取到的內容進行正則匹配。
fav_nums = response.css(".bookmark-btn::text").extract_first()
match_re = re.match(".*?(\d+).*", fav_nums)
if match_re:
fav_nums = match_re.group(1)
comment_nums = response.css(".hide-on-480::text").extract()[-1]
match_re = re.match(".*?(\d+).*", comment_nums)
if match_re:
comment_nums = match_re.group(1)
當我們提取標籤的時,發現其中['實踐專案', ' 1 評論 ', 'OpenCV', 'tensorflow', '機器學習']
還有1 評論
,這並不是我們希望看到的,所以我們得用正則匹配把無用的資訊剔除掉。
tag_list = response.css(".entry-meta a::text").extract()
tag_list = [element for element in tag_list if not element.strip().endswith("評論")]
tags = ",".join(tag_list)
到此為止,我們的程式程式碼就已經分析完成了。
主要程式碼:
import scrapy
import re
class jobboleSpider(scrapy.Spider):
name = "jobbole_spider"
start_urls = ['http://python.jobbole.com/89004/']
def parse(self, response):
fav_nums = response.css(".bookmark-btn::text").extract_first()
match_re = re.match(".*?(\d+).*", fav_nums)
if match_re:
fav_nums = match_re.group(1)
comment_nums = response.css(".hide-on-480::text").extract()[-1]
match_re = re.match(".*?(\d+).*", comment_nums)
if match_re:
comment_nums = match_re.group(1)
tag_list = response.css(".entry-meta a::text").extract()
tag_list = [element for element in tag_list if not element.strip().endswith("評論")]
tags = ",".join(tag_list)
for quote in response.css(".grid-8"):
yield{
'title': quote.css(".type-post h1::text").extract_first(),
'create_data': quote.css(".entry-meta-hide-on-mobile::text").extract_first().strip()[:-2],
'tags': tags,
'praise_nums': quote.css(".vote-post-up h10::text").extract_first(),
'fav_nums': fav_nums,
'comment_nums': comment_nums,
}
另外,要想在PyCharm
上執行此程式,還需要新建一個main.py
函式
import os
import sys
from scrapy.cmdline import execute
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
execute(["scrapy", "crawl", "jobbole_spider"])
執行main.py
函式,得到執行結果。
2018-02-11 15:31:57 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://python.jobbole.com/robots.txt> (referer: None)
2018-02-11 15:31:57 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://python.jobbole.com/89004/> (referer: None)
2018-02-11 15:31:58 [scrapy.core.scraper] DEBUG: Scraped from <200 http://python.jobbole.com/89004/>
{'title': '15 分鐘用 ML 破解一個驗證碼系統', 'create_data': '2018/01/29', 'tags': '實踐專案,OpenCV,tensorflow,機器學習', 'praise_nums': '5', 'fav_nums': '13', 'comment_nums': '1'}
2018-02-11 15:31:58 [scrapy.core.engine] INFO: Closing spider (finished)
感興趣的朋友可以自己抓取網頁上的正文內容。
歡迎關注我的個人公眾號。