1.準備
- 安裝:pip install scrapy==1.1.0rc3
- 參考資料:官方1.0文檔
2.使用Scrapy重構代碼
2.1創建新項目
-
使用cmd進入待建項目的文件夾中,輸入:
scrapy startproject 項目名
項目就建好了,項目結構圖如下:
- spiders文件夾是存放各種爬蟲的文件夾
items是存儲爬取對象的屬性定義的文件
settings是Scrapy設置的文件
2.2 定義要爬取的對象的屬性
- 在items.py中添加:
class BookName(Item):
name=Field()
url=Field()
class BookContent(Item):
id=Field()
title=Field()
text=Field()
2.3 定義爬蟲
- 在Spider文件夾內添加文件book.py。并書寫代碼如下:
class BookSpider(CrawlSpider):
name="book"#爬蟲名字
allowed_domains=["shicimingju.com"]#允許的域名
start_urls=[#開始爬取的網站
"http://www.shicimingju.com/book/sanguoyanyi.html"
]
- 我直接是使用的CrawlSpider,一個更加方便定義爬取連接規則的類型。
allow對應爬取的網站,使用了正則,callback對應對于該網站使用的方法。
rules=(
Rule(LinkExtractor(allow=('http://www.shicimingju.com/book/sanguoyanyi.html',)),callback='bookMenu_item'),
Rule(LinkExtractor(allow="http://www.shicimingju.com/book/.*?\d*?\.html"),callback="bookContent_item")
)
- 讀取書的名字
def bookMenu_item(self,response):
sel=Selector(response)
bookName_items=[]
bookName_item=BookName()
bookName_item['name']=sel.xpath('//*[@id="bookinfo"]/h1/text()').extract()
print(bookName_item)
bookName_items.append(bookName_item)
return bookName_items
- 讀取每章內容并保存id順序,因為Scrapy是異步的,所以需要保存章節順序。
def bookContent_item(self,response):
global num
print(num)
num+=1
sel = Selector(response)
bookContent_items = []
bookContent_item = BookContent()
bookContent_item['id']=re.findall('.*?(\d+).*?',response.url)
bookContent_item['title']=sel.xpath('//*[@id="con"]/h2/text()').extract()
bookContent_item['text']="".join(sel.xpath('//*[@id="con2"]/p/descendant::text()').extract())
bookContent_item['text']=re.sub('\xa0',' ',bookContent_item.get('text'))
print(bookContent_item)
bookContent_items.append(bookContent_item)
return bookContent_items
2.4 執行爬蟲
- 普通的執行方法,在cmd中輸入:
scrapy crawl book - 在pycharm中的執行方法 stackoverflow
3.總結
- 可能會出現的問題:
- ImportError : cannot import name '_win32stdio' 解決方法
- python3 使用scrapy的crawlspider問題 解決方法:查看最新的官方文檔。
- xpath: 所有"< p >"標簽下的內容:xpath('//p/descendant::text()')
只需要< p >或者< strong >下內容:xpath('//p/text()|//p/strong/text()')
xpath也是個大坑,改天把它填了。