Scrapy 爬蟲 --四個步驟--
課程設計要用到爬蟲,稍微回顧下,Scrapy的爬蟲四步走....只是簡單的Scrapy,什麼分散式爬蟲啥的,感覺以後再說了....不談了...
1、建立專案
cmd >> scrapy startproject douban## scrapy startproject project_name
cmd >> cd douban/douban/spiders
cmd >> scrapy genspider douban_spider movie.douban.com## scrapy genspider spider_text_name start_url
Scrapy包含上圖幾個部件:
1、Scrapy Engine
引擎負責控制資料流在系統中所有元件中流動,並在相應動作發生時觸發事件。
2、Scheduler
排程器從引擎接受request並將他們入隊,以便之後引擎請求他們時提供給引擎;簡單的說就是排程佇列,same as 作業系統中的排程佇列.......
3、Downloader
下載器負責獲取頁面資料並提供給引擎,而後提供給spider。
4、Spiders
Spider是Scrapy使用者編寫用於分析response並提取item(即獲取到的item)或額外跟進的URL的類。 每個spider負責處理一個特定(或一些)網站。
5、Item Pipeline
Item Pipeline負責處理被spider提取出來的item。典型的處理有清理、 驗證及持久化(例如存取到資料庫中)。
6、Downloader middlewares
下載器中介軟體是在引擎及下載器之間的specific hook,處理Downloader傳遞給引擎的response。 其提供了一個簡便的機制,通過插入自定義程式碼來擴充套件Scrapy功能。
7、Spider middlewares
Spider中介軟體是在引擎及Spider之間的specific hook,處理spider的輸入(response)和輸出(items及requests)。 其提供了一個簡便的機制,通過插入自定義程式碼來擴充套件Scrapy功能。
scrapy.cfg
: 專案的配置檔案;project_modul/
: 該專案的python模組。之後您將在此加入程式碼;project_modul/items.py
: 專案中的item檔案;project_modul/pipelines.py
: 專案中的pipelines檔案;project_modul/settings.py
: 專案的設定檔案;project_modul/spiders/
: 放置spider程式碼的目錄;
2、明確目標
即瞭解你要哪些資料 ——>>> item.py
class DoubanItem(scrapy.Item):
#序號
serial_number = scrapy.Field()
#電影名稱
movie_name = scrapy.Field()
#介紹
introduce = scrapy.Field()
#星級
star = scrapy.Field()
#描述
describe = scrapy.Field()熟悉Django的朋友一定會注意到Scrapy Item定義方式與Django Models很類似, 不過沒有那麼多不同的欄位型別(Field type),更為簡單。
3、爬蟲檔案的編寫 ——>>> spiders [folders]
Spider類定義瞭如何爬取某個(或某些)網站。包括了爬取的動作以及如何從網頁的內容中提取結構化資料(爬取item)。 換句話說,Spider就是您定義爬取的動作及分析某個網頁(或者是有些網頁)的地方。
能夠獲取兩類資料,一種就是純資料,比如Title啥的,另外一種資料就是可遞迴的資料,即資料多的時候有好幾頁資料,裡面的第二頁,第幾頁就是可遞迴的連結資料
以初始的URL初始化Request,並設定回撥函式。 當該request下載完畢並返回時,將生成response,並作為引數傳給該回調函式。
spider中初始的request是通過呼叫 start_requests() 來獲取的。 start_requests() 讀取 start_url中的URL, 並以 Parse 為回撥函式生成Request 。
在回撥函式內分析返回的(網頁)內容,返回 Item 物件或者Request或者一個包括二者的可迭代容器。 返回的Request物件之後會經過Scrapy處理,下載相應的內容,並呼叫設定的callback函式(函式可相同)。
在回撥函式內,您可以使用選擇器(Selectors) (您也可以使用BeautifulSoup, lxml 或者您想用的任何解析器) 來分析網頁內容,並根據分析的資料生成item。
最後,由spider返回的item將被存到資料庫(由某些Item Pipeline處理)或使用Feed exports存入到檔案中。
class DoubanSpiderSpider(scrapy.Spider):
#爬蟲名 #與專案名不同
name = 'douban_spider'
#域名 #不在這個域名下不解析
allowed_domains = ['movie.douban.com']
#入口url,並將入口URL 扔進排程器【Schedule】中
start_urls = ['https://movie.douban.com/top250']
#扔進排程器【Schedule】之後,Schedule 告訴爬蟲引擎自己準備好了,然後爬蟲引擎讓Downloader去下載數 據,獲取頁面
#然後將獲取的頁面返回值Spider檔案中,讓Spider進行解析,那如何解析檔案就是下面的parse方法,這個 response就是Downloader的返回值,可以詳細見上面的那張圖
def parse(self, response):
print(response.text)
cmd >> scrapy crawl spider_name
可能遇見錯誤一:編碼問題
import sys,io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030')可能遇見錯誤二:不給解析
USER_AGENT = 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Mobile Safari/537.36' #網站上自己看USER_AGENT
爬取第一類資料:純資料
class DoubanSpiderSpider(scrapy.Spider):
#爬蟲名 #與專案名不同
name = 'douban_spider'
#域名 #不在這個域名下不解析
allowed_domains = ['movie.douban.com']
#入口url,並將入口URL 扔進排程器【Schedule】中
start_urls = ['https://movie.douban.com/top250']
#扔進排程器【Schedule】之後,Schedule 告訴爬蟲引擎自己準備好了,然後爬蟲引擎讓Downloader去下載資料, 獲取頁面
#然後將獲取的頁面返回值Spider檔案中,讓Spider進行解析,那如何解析檔案就是下面的parse方法,這個response 就是Downloader
#的返回值,可以詳細見上面的那張圖
def parse(self, response):
movie_list=response.xpath("//div[@class='article']//ol[@class='grid_view']//li")
for i in movie_list:
Douban_item=DoubanItem() ##匯入item包,你要存到item中
Douban_item['serial_number']=i.xpath(".//div[@class='item']//em/text()").extract_first() #獲取第一個資料
#如果有多個數據,你想把資料拼接起來
#content=i.xpath(...).extract()
#for ii in content:
# c_s="".join(ii.split())
# =
print(Douban_item)
#將資料返回至pipe中,請仔細看scrapy的流程圖就知道了,不加yield不行
yield Douban_item
爬取第二類資料:下頁資料
next_link = response.xpath("//span[@class='next']/link/@href").extract()
if next_link:
next_link=next_link[0]
yield scrapy.Request("https://movie.douban.com/top250"+next_link,callback=self.parse)
4、儲存內容
將爬取的資料匯出json檔案,csv檔案
cmd >> scrapy crawl spider_name -o _name.json
cmd >> scrapy crawl spider_name -o _name.csv
儲存檔案至資料庫
---settings.py--- # 先寫資料庫配置檔案
MYSQL_HOST = 'localhost'
MYSQL_DBNAME = 'scrapy'
MYSQL_USER = 'root'
MYSQL_PASSWD = ''
MYSQL_PORT = 3306
---pipelines.py--- # 傳入資料
import pymysql ##匯入python中的mysql包,pymysql
from project.settings import MYSQL_HOST,MYSQL_DBNAME,MYSQL_USER,MYSQL_PASSWD,MYSQL_PORT
class DoubanPipeline(object):
def process_item(self, item, spider):
# open db
self.connect = pymysql.connect(
host=MYSQL_HOST,port=MYSQL_PORT,user=MYSQL_USER,db=MYSQL_DBNAME,
passwd=MYSQL_PASSWD,charset='utf8',use_unicode=True)
self.cursor = self.connect.cursor()
# insert db
num = item['serial_number']
sql = 'insert into test(num) values("%s")' % (num)
self.cursor.execute(sql)
self.connect.commit()
# close db
self.cursor.close()
self.connect.close()
return item
---settings.py--- #開啟管道 ITEM_PIPELINES ,取消下面這個註釋
ITEM_PIPELINES = {
'douban.pipelines.DoubanPipeline': 300,
}