Scrapy爬取小說簡單邏輯


Scrapy爬取小說簡單邏輯

 一 准備工作

1)安裝Python

2)安裝PIP
3)安裝scrapy
4)安裝pywin32
5)安裝VCForPython27.exe

...........

具體安裝步驟,可參考http://www.cnblogs.com/zyj-python/p/7392476.html

 

 二 爬蟲邏輯

 

1.CMD終端創建爬蟲項目
cd Desktop(返回桌面目錄) #選擇文件保存位置,我放在了桌面

Scrapy startProject BooksSpider  #BooksSpider為項目名稱,自己起名

    (ps:CMD終端顯示"rou can start your first spider with:"表示項目創建成功)
 
2.創建爬蟲文件
拖動爬蟲項目文件用Pycharm打開,點擊左下角Terminal打開終端
scrapy genspider books(蜘蛛名,自定義,不能重復,可以修改但不建議修改) www.qisuu.com(網站域名, 這里以奇書網為例)
3.雙擊打開爬蟲文件(蜘蛛文件.py),在Spiders包中引用可能用到的包
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
import scrapy
import urlparse
from ..items import BooksItem

 

(ps:文件夾圖標中帶空心圓為包,只有包才能直接引入,帶__init__.py的文件,
沒有則表示文件夾)
以下是創建爬蟲文件自帶:
class BooksSpider(scrapy.Spider):
    name = 'books'
    allowed_domains = ['www.qisuu.com']
    start_urls = ['http://www.qisuu.com/']

    def parse(self, response):
  pass

 

4.明確爬取目標
以奇書網為例:
1)請求導航條上每個按鈕對應頁面
2)分別解析每個頁面的電子書列表(主要獲得電子書詳情URL)
3)請求詳情URL,解析電子書的詳細信息(書名,封面,評分,大小....下載地址)
4)根據下載地址下載電子書到本地
制作爬蟲:
  在books.py中
# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
import scrapy
import urlparse
from ..items import BooksItem


class BooksSpider(scrapy.Spider): name = 'books' allowed_domains = ['www.qisuu.com'] start_urls = ['http://www.qisuu.com/']

   #獲取首頁導航條的url
def parse(self, response): a_list=response.xpath("//div[@class='nav']/a[@target='_blank']") for a in a_list: #分類名稱 category_namme=a.xpath("text()").extract_first("") #拼接完整的分類url category_url=urlparse.urljoin(response.url,a.xpath("@href").extract_first(""))

       #yield將結果返回調度器 #將分類地址轉發給downloader下載並將結果傳給parse_books_list #meta:專門用來傳遞參數,類型是字典
yield scrapy.Request( url=category_url, callback=self.parse_books_list, meta={"category_namme":category_namme,} )     

   #獲取分類頁面的所有url def parse_books_list(self,response): href_list
=response.xpath("//div[@class='listBox']/ul/li/a/@href").extract() for href in href_list: list_href=urlparse.urljoin(response.url,href) yield scrapy.Request( url=list_href, callback=self.parse_books_detail, meta=response.meta, # meta={"category_namme": response.meta['category_namme'],} )
      #獲取所有頁數,並循環獲得每一頁的url all_pages
=response.xpath("//select[@name='select']/option/@value").extract() for page in all_pages: detail_url=urlparse.urljoin(response.url,page) yield scrapy.Request( url=detail_url, callback=self.parse_books_list, meta=response.meta )     

   #獲取每個小說的詳情 def parse_books_detail(self,response): info_div
=response.xpath("//div[@class='detail_right']") title=info_div.xpath("h1/text()").extract_first("") li_list=info_div.xpath("ul/li") size=li_list[2].xpath("text()").extract_first("") size=size.replace(u"文件大小:","").strip() date_time=li_list[4].xpath("text()").extract_first("") date_time=date_time.replace(u"發布日期:","").strip() user=li_list[6].xpath("a/text()").extract_first("") download_times=li_list[1].xpath("text()").extract_first("") download_times = download_times.replace(u"下載次數:", "").strip() book_degree=li_list[7].xpath("em/@class").extract_first("") book_degree = book_degree.replace("lstar","").strip() download_url=response.xpath("//a[@class='downButton']/@href")[1].extract() img_url=response.xpath("//div[@class='detail_pic']/img/@src").extract_first("") img_url=urlparse.urljoin(response.url,img_url) category_namme=response.meta['category_namme'] print title,user,date_time,category_namme item=BooksItem() item['title']=title item['size']=size item['date_time']=date_time item['user']=user item['download_times']=download_times item['book_degree']=book_degree item['download_url'] = [u"%s"%download_url] #當下在路徑有亂碼,加u 小說要以GBK格式存儲,有中文時要進行編碼 item['img_url']=[img_url] item['category_namme']=category_namme yield item
    #yield 將結果返回給items.py文件

  代碼中的xpath與正則表達式是一樣的,只是用法更加簡單方便, 具體操作可百度, 此處不細說.

  在items.py文件中

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html

import scrapy


class BooksspiderItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    # pass
   class BooksItem(scrapy.Item):
    title = scrapy.Field()
    size = scrapy.Field()
    date_time = scrapy.Field()
    user = scrapy.Field()
    download_times = scrapy.Field()
    book_degree = scrapy.Field()
    download_url = scrapy.Field()
    img_url = scrapy.Field()
    category_namme = scrapy.Field()

#自定義一個類,用來接收獲取到的數據
#Field()可以接受任何類型的參數

這時就可以開始爬蟲了, 代碼為:

scrapy crawl books -o book.json -s FEED_EXPORT_ENCODING = utf-8

  其中 scrapy crawl books 是運行books爬蟲程序, -o book.json 為以json格式保存, FEED_EXPORT_ENCODING = utf-8 為編碼格式

友情提示: 不要輕易去爬蟲,只有確定自己代碼沒有問題才可以,可以先使用終端測試(cmd),將代碼一行一行依次粘貼運行

scrapy shell http://www.qisuu.com
  (ps:利用CMD終端測試,不要輕易去爬蟲,成功末尾顯示IN[1],然后依次在終端復制粘貼進去
  相關代碼,包括相關引入import代碼,利用xpath取特定數據可在終端打印查看效果,有時要回
  車兩次展示,在目標網站沒有反爬蟲協議或所需數據極少時可考慮在Terminal直接運行)

如果想要下載至本地:

需要修改settings.py文件

ITEM_PIPELINES = {
   # 'BooksSpider.pipelines.BooksspiderPipeline': 300,
    "scrapy.pipelines.images.ImagesPipeline":1,
    "scrapy.pipelines.files.FilesPipeline":2,
}
IMAGES_URLS_FIELD = "img_url"
IMAGES_STORE = "imgs"
FILES_URLS_FIELD = "download_url"
FILES_STORE = "files"
  找到ITEM_PIPELINES,大約在67行,做出如上修改,IMAGES_URLS_FIELD獲取下載圖片的url, IMAGES_STORE新建一個文件夾,用來存放圖片 FILES用法魚IMAGES一致

可能存在的問題,原因及解決方案:

1.網站源代碼結構與請求到的代碼結構可能不一致
(如tbody只在瀏覽器渲染的結構中有而請求出來的沒有)
解決方案:優化xpath寫法,或改用正則表達式
2.請求robots.txt后顯示200意為請求到反爬蟲協議成功會自動停止爬蟲程序
解決方案:設置不遵守robots.txt反爬蟲協議,強行進入
3.在請求到某個url顯示200成功后卻突然自動停止爬蟲(closing spider)
可能原因:若顯示Filtered offsite request則意為scrapy自動過濾該url把它放入了黑名單
解決方案:在該url代碼運行的函數meta字典中加入dont_filter = True默認
True不要過濾,若改為False則是要過濾
 
以上就是Scrapy爬蟲的基本邏輯!
 
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM