python scrapy菜鸟教程_scrapy学习笔记(一)快速入门
安裝Scrapy
Scrapy是一個高級的Python爬蟲框架,它不僅包含了爬蟲的特性,還可以方便的將爬蟲數據保存到csv、json等文件中。
首先我們安裝Scrapy。
pip install scrapy
在Windows上安裝時可能會出現錯誤,提示找不到Microsoft Visual C++。這時候我們需要到它提示的網站visual-cpp-build-tools下載VC++ 14編譯器,安裝完成之后再次運行命令即可成功安裝Scrapy。
error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools
快速開始
第一個爬蟲
以下是官方文檔的第一個爬蟲例子。可以看到,和我們手動使用request庫和BeautifulSoup解析網頁內容不同,Scrapy專門抽象了一個爬蟲父類,我們只需要重寫其中的方法,就可以迅速得到一個可以不斷爬行的爬蟲。
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
def start_requests(self):
urls = [
'http://quotes.toscrape.com/page/1/',
'http://quotes.toscrape.com/page/2/',
]
for url in urls:
yield scrapy.Request(url=url, callback=self.parse)
def parse(self, response):
page = response.url.split("/")[-2]
filename = 'quotes-%s.html' % page
with open(filename, 'wb') as f:
f.write(response.body)
self.log('Saved file %s' % filename)
上面的爬蟲有幾個地方需要解釋一下:
爬蟲類的name屬性,用來標識爬蟲,該名字在一個項目必須是唯一的。
start_requests()方法,必須返回一個可迭代的列表(可以是列表,也可以是生成器),Scrapy會從這些請求開始抓取網頁。
parse() 方法用于從網頁文本中抓取相應內容,我們需要根據自己的需要重寫該方法。
開始鏈接
在上面的例子中使用start_requests()方法來設置起始URL,如果只需要簡單指定URL還可以使用另一種簡便方法,那就是設置類屬性start_urls,Scrapy會讀取該屬性來設置起始URL。
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
start_urls = [
'http://quotes.toscrape.com/page/1/',
'http://quotes.toscrape.com/page/2/',
]
提取數據
這部分的練習可以使用Scrapy的shell功能。我們可以使用下面的命令啟動Scrapy shell并提取百思不得姐段子的內容,成功運行之后會打開一個交互式shell,我們可以進行交互式編程,隨時查看代碼的運行結果。
scrapy shell 'http://www.budejie.com/text/'
可能會出現下面的錯誤,遇到這種情況是因為沒有安裝pypiwin32模塊。
ModuleNotFoundError: No module named 'win32api'
這時候可以使用下面的命令安裝。
pip install pypiwin32
運行成功之后在終端中看到以下內容,列舉了在交互式shell中可以進行的操作。
[s] Available Scrapy objects:
[s] scrapy scrapy module (contains scrapy.Request, scrapy.Selector, etc)
[s] crawler
[s] item {}
[s] request
[s] response <200 http://www.budejie.com/text/>
[s] settings
[s] spider
[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
例如,如果我們要查看網頁的內容,可以輸入view(response),會打開默認瀏覽器并進入相應頁面。
In [2]: view(response)
Out[2]: True
如果需要使用CSS選擇器提取網頁內容,可以輸入相應的內容,比如說下面就獲取了網頁上的標題標簽。
In [3]: response.css('title')
Out[3]: []
如果需要提取標簽內容,可以使用Scrapy擴展的CSS選擇器::text并使用extract()方法。如果直接對標簽調用extract()會獲取包含標簽在內的整個文本。
In [8]: response.css('title::text').extract()
Out[8]: ['內涵段子_內涵笑話-百思不得姐官網,第1頁']
如果選中的標簽含有復數內容,可以使用extract_first()方法獲取第一個元素。
response.css('title::text').extract_first()
也可以使用索引來選取內容。不過假如沒有元素的話,extract_first()方法會返回None而索引會拋出IndexError,因此使用extract_first()更好。
response.css('title::text')[0].extract()
除了CSS選擇器之外,Scrapy還支持使用re方法以正則表達式提取內容,以及xpath方法以XPATH語法提取內容。關于XPATH,可以查看菜鳥教程,寫的還不錯。
下面是提取百思不得姐段子的簡單例子,在交互環境中執行之后,我們就可以看到提取出來的數據了。
li=response.css('div.j-r-list-c-desc')
content=li.css('a::text')
編寫爬蟲
確定如何提取數據之后,就可以編寫爬蟲了。下面的爬蟲爬取了百思不得姐首頁的用戶名和段子。
class Baisibudejie(scrapy.Spider):
name = 'jokes'
start_urls = ['http://www.budejie.com/text/']
def parse(self, response):
lies = response.css('div.j-r-list >ul >li')
for li in lies:
username = li.css('a.u-user-name::text').extract()
content = li.css('div.j-r-list-c-desc a::text').extract()
yield {'username': username, 'content': content}
寫好了爬蟲之后,就可以運行了。我們可以使用下面的命令運行這個爬蟲。運行成功之后,會出現user.json,其中就是我們爬取的數據。Scrapy支持多種格式,除了json之外,還可以將數據導出為XML、CSV等格式。
scrapy runspider use_scrapy.py -o user.json
頁面跳轉
如果爬蟲需要跨越多個頁面,需要在parse方法中生成下一步要爬取的頁面。下面的例子是爬取我CSDN博客所有文章和連接的爬蟲。這個爬蟲沒有處理CSDN博客置頂文章,所以置頂文章爬取的文章標題是空。
class CsdnBlogSpider(scrapy.Spider):
name = 'csdn_blog'
start_urls = ['http://blog.csdn.net/u011054333/article/list/1']
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.base_url = 'http://blog.csdn.net'
def parse(self, response):
articles = response.css('div#article_list div.article_item')
for article in articles:
title = article.css('div.article_title a::text').extract_first().strip()
link = self.base_url + article.css('div.article_title a::attr(href)').extract_first().strip()
yield {'title': title, 'link': link}
pages = response.css('div#papelist')
next_page_url = pages.css('a').re_first('下一頁')
if next_page_url is not None:
yield scrapy.Request(urllib.parse.urljoin(self.base_url, next_page_url))
scrapy命令
為了更好的實現工程化管理,Scrapy還提供了scrapy命令來幫助我們管理爬蟲。詳細的命令用法請參考官方文檔。
創建項目
下面的命令可以創建一個Scrapy爬蟲項目,它為我們規定了標準的項目格式。
scrapy startproject myproject [project_dir]
創建好之后,應該會出現如下的項目結構。spiders模塊中放置所有爬蟲,scrapy.cfg是項目的全局配置文件,其余文件是Scrapy的組件。
創建爬蟲
使用下面的命令可以創建一個爬蟲,爬蟲會放置在spider模塊中。
scrapy genspider mydomain mydomain.com
生成的爬蟲具有基本的結構,我們可以直接在此基礎上編寫代碼。
# -*- coding: utf-8 -*-
import scrapy
class MydomainSpider(scrapy.Spider):
name = "mydomain"
allowed_domains = ["mydomain.com"]
start_urls = ['http://mydomain.com/']
def parse(self, response):
pass
運行爬蟲
在已經生成好的項目中,我們使用項目相關的命令來運行爬蟲。首先需要列出所有可運行的爬蟲,這會列出所有爬蟲類中指定的name屬性。
scrapy list
然后,我們可以按照name來運行爬蟲。
scrapy crawl 'csdn_blog' -o blog.json
注意這兩個命令都是項目相關的,只能用于已存在的項目。
設置編碼
如果你使用上面的爬蟲并導出為json格式,可能會發現所有漢字全變成了Unicode字符(類似\uA83B這樣的)。自Scrapy1.2 起,增加了FEED_EXPORT_ENCODING屬性,用于設置輸出編碼。我們在settings.py中添加下面的配置即可。
FEED_EXPORT_ENCODING = 'utf-8'
然后再重新導出一次。這次所有漢字都能正常輸出了。
以上就是Scrapy的快速入門了。我們了解了如何編寫最簡單的爬蟲。如果查閱Scrapy的官方文檔會發現Scrapy的功能遠不止這里介紹的。本文就是起一個拋磚引玉的作用,如果希望進一步了解Scrapy這個爬蟲框架,請查閱相關文檔進一步學習。
總結
以上是生活随笔為你收集整理的python scrapy菜鸟教程_scrapy学习笔记(一)快速入门的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java注解的执行顺序_深入理解Spri
- 下一篇: python中opencv中inrang