利用scrapy爬取簡(jiǎn)書(shū)文章并保存到數(shù)據(jù)庫(kù)

這篇文章主要是介紹利用scrapy爬取簡(jiǎn)書(shū)IT專(zhuān)欄的文章,并把爬取結(jié)果保存到數(shù)據(jù)庫(kù)中。所以實(shí)現(xiàn)這些功能的前提電腦中安裝了scrapy,MySQL數(shù)據(jù)庫(kù),和一些爬蟲(chóng)的基本知識(shí)。代碼我會(huì)詳細(xì)介紹。如果有問(wèn)題也可以給我留言。

簡(jiǎn)介

scrapy

官方文檔的介紹是“Scrapy是一個(gè)為了爬取網(wǎng)站數(shù)據(jù),提取結(jié)構(gòu)性數(shù)據(jù)而編寫(xiě)的應(yīng)用框架。 可以應(yīng)用在包括數(shù)據(jù)挖掘,信息處理或存儲(chǔ)歷史數(shù)據(jù)等一系列的程序中。”我現(xiàn)在對(duì)它了解還不是很多,知道它的功能很強(qiáng)大,但還只會(huì)做一些簡(jiǎn)單的爬取。

MySQL數(shù)據(jù)庫(kù)

MySQL是一種開(kāi)放源代碼的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng)(RDBMS),MySQL數(shù)據(jù)庫(kù)系統(tǒng)使用最常用的數(shù)據(jù)庫(kù)管理語(yǔ)言–結(jié)構(gòu)化查詢(xún)語(yǔ)言(SQL)進(jìn)行數(shù)據(jù)庫(kù)管理。

安裝方法我在這里就贅述了,網(wǎng)上有很多方法。因?yàn)槲野惭bscrapy的方法不是最簡(jiǎn)單的,所以我就不介紹我的方法了;至于MySQL,這個(gè)比較容易。安裝好直接就可以使用了。

功能實(shí)現(xiàn)

scrapy部分

我們的目的是抓取簡(jiǎn)書(shū)@IT·互聯(lián)網(wǎng)專(zhuān)題,網(wǎng)址是:

http://www.itdecent.cn/c/V2CqjW

這個(gè)網(wǎng)址的確可以抓取到內(nèi)容,但只是極少部分,在瀏覽的過(guò)程中還會(huì)繼續(xù)加載內(nèi)容,所以這個(gè)網(wǎng)址是不對(duì)的。我們必須獲取它的真實(shí)網(wǎng)址才行。這就用到了抓包。

通過(guò)抓包我們獲取到的真實(shí)網(wǎng)址是:

http://www.itdecent.cn/c/V2CqjW?order_by=commented_at&page=1

應(yīng)該已經(jīng)注意到了,真正有用的是page,我們?cè)谧ト〉臅r(shí)候只要改變頁(yè)數(shù)就能實(shí)現(xiàn)多頁(yè)抓取。

按下win+R,輸入cmd運(yùn)行終端,輸入scrapy startproject jianshu等待scrapy自動(dòng)生成文件,在jianshu->jianshu->spiders文件夾下創(chuàng)建jianshuspider.py文件。

jianshuspider.py代碼部分:

from scrapy.spider import Spider
from jianshu.items import JianshuItem
class JianshuSpider(Spider):
    name = 'jianshu'
    box = []
    for num in range(120):
        pages = 'http://www.itdecent.cn/c/V2CqjW?order_by=commented_at&page={0}'.format(num)
        box.append(pages)
    start_urls = box
    def parse(self, response):
        item = JianshuItem()
        articles = response.xpath("http://ul[@class='note-list']/li")
        for article in articles:
            item['author'] = article.xpath('.//div[@class="name"]/a/text()').extract()[0]
            item['title'] = article.xpath('.//div[@class="content"]/a/text()').extract()[0]
            item['times'] = article.xpath('.//div[@class="name"]/span/@data-shared-at').extract()[0]
            url = article.xpath('.//div[@class="content"]/a/@href').extract()[0]
            item['url'] = 'http://www.itdecent.cn' + url
            admire = article.xpath('.//div/div[2]/span[2]/text()').extract()
            item['admire'] = ''.join(admire)
            likes = article.xpath('.//div/div[2]/span[1]/text()').extract()
            item['likes'] = ''.join(likes)
            yield item

我來(lái)介紹一下這段代碼。

name是以后運(yùn)行爬蟲(chóng)的名字,start_urls是爬取的網(wǎng)站,是一個(gè)列表,因?yàn)槲覀円ト『芏囗?yè),所以我定義了一個(gè)空列表用來(lái)存放不同頁(yè)數(shù)的網(wǎng)址。parse部分可以說(shuō)就是用來(lái)把爬取到的內(nèi)容傳遞給item。我們抓取了簡(jiǎn)書(shū)文章的作者、文章標(biāo)題、創(chuàng)建的時(shí)間、文章的網(wǎng)址、贊賞和喜歡。

在篩選信息的過(guò)程中用到了xpath,其實(shí)只要多看看別人的代碼,自己研究研究,很好理解的。jianshuspider.py這部分代碼篩選出需要的結(jié)果后,我們就開(kāi)始寫(xiě)items.py。

items.py代碼部分:

import scrapy
class JianshuItem(scrapy.Item):
    title = scrapy.Field()
    author = scrapy.Field()
    times = scrapy.Field()
    url = scrapy.Field()
    admire = scrapy.Field()
    likes = scrapy.Field()

這部分代碼就是對(duì)應(yīng)的要抓取的內(nèi)容。很好理解。正常情況下,在jianshu的文件夾下運(yùn)行命令提示符,輸入scrapy crawl jianshu
就可以看到運(yùn)行結(jié)果了。因?yàn)槲覀円4娴綌?shù)據(jù)庫(kù),所以還得繼續(xù)完成代碼。

MySQL部分

這部分用到了數(shù)據(jù)庫(kù)的知識(shí),安裝好數(shù)據(jù)庫(kù)以后,在數(shù)據(jù)庫(kù)的終端登錄以后,輸入CREATE DATABASE jianshu;,然后輸入U(xiǎn)SE jianshu;,在使用jianshu數(shù)據(jù)庫(kù)后,所有的操作就都在這個(gè)數(shù)據(jù)庫(kù)里了。在結(jié)束命令的時(shí)候一定要記得輸入“;”分號(hào)。然后就是創(chuàng)建新表。輸入:

CREATE TABLE articles (id BIGINT(5) NOT NULL AUTO_INCREMENT, title VARCHAR(100), author VARCHAR(100), times VARCHAR(100), url VARCHAR(100), admire VARCHAR(1000), likes VARCHAR(1000))

這樣就創(chuàng)建好了表,如果輸入無(wú)誤的話輸入DESCRIBE articles;就可以查看表的數(shù)據(jù)結(jié)構(gòu)了。如圖:

scrapy保存到數(shù)據(jù)庫(kù)

創(chuàng)建好新表,我們就可以寫(xiě)pipelines.py的代碼了。

pipelines.py代碼部分:

import pymysql
def dbHandle():
    conn = pymysql.connect(
        host = "localhost",
        user = "root",
        passwd = "root",
        charset = "utf8",
        use_unicode = False
    )
    return conn
class JianshuPipline(object):
    def process_item(self,item,spider):
        dbObject = dbHandle()
        cursor = dbObject.cursor()
        cursor.execute("USE jianshu")
        sql = "INSERT INTO articals(author,title,times,url,admire,likes) VALUES(%s,%s,%s,%s,%s,%s)"
        try:
            cursor.execute(sql,(item['author'],item['title'],item['times'],item['url'],item['admire'],item['like']))
            cursor.connection.commit()
        except BaseException as e:
            print("錯(cuò)誤在這里>>>>>>>>>>>>>",e,"<<<<<<<<<<<<<錯(cuò)誤在這里")
            dbObject.rollback()
        return item

代碼分為兩部分,第一部分用來(lái)連接數(shù)據(jù)庫(kù),第二部分用來(lái)用來(lái)向數(shù)據(jù)庫(kù)傳入數(shù)據(jù)。

如果這段代碼不是太明白可以先看這部分代碼,Python操作數(shù)據(jù)庫(kù)的代碼:

#導(dǎo)入pymysql模塊
import pymysql
#連接數(shù)據(jù)庫(kù)
conn = pymysql.connect(host='127.0.0.1', user='root', passwd='root', db='music')
cur = conn.cursor()
#輸入使用數(shù)據(jù)庫(kù)和查詢(xún)信息的命令,操作類(lèi)似在cmd中的輸入
cur.execute("USE music")
#插入數(shù)據(jù)(pages是數(shù)據(jù)庫(kù)music下的表)
cur.execute("INSERT INTO pages(title,content) VALUES('449454051','http://m2.music.126.net/GvSlxgdwVCKelv3gFaw9pg==/18641120138988064.mp3')")
cur.connection.commit()
#更新數(shù)據(jù)
cur.execute("SELECT * FROM pages")
print("獲取全部信息\n",cur.fetchall())
#關(guān)閉數(shù)據(jù)庫(kù)
cur.close()
conn.close()

先導(dǎo)入pymysql庫(kù),然后定義函數(shù),用來(lái)存放數(shù)據(jù)庫(kù)信息。下邊的JianshuPipline在創(chuàng)建文件時(shí)自動(dòng)生成。我們只要添加往數(shù)據(jù)庫(kù)導(dǎo)入信息的代碼就可以了。

我們還需要改一改settings.py中的代碼,把下邊的代碼添加和修改一下就行了。

settings.py代碼:

ROBOTSTXT_OBEY = False #True 修改為 False

#添加請(qǐng)求頭
DEFAULT_REQUEST_HEADERS = {
'accept': 'image/webp,*/*;q=0.8',
'accept-language': 'zh-CN,zh;q=0.8',
'referer': 'http://www.itdecent.cn/',
'user-agent': 'Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36',
}

#連接數(shù)據(jù)庫(kù)
ITEM_PIPELINES = {
'jianshu.pipelines.JianshuPipline': 300,
}

這樣就算大功告成了。查看數(shù)據(jù)庫(kù),如圖:

總結(jié)

在迷迷糊糊看完上邊的教程之后我們總結(jié)一下。

scrapy組件的作用

Item 對(duì)象是種簡(jiǎn)單的容器,保存了爬取到得數(shù)據(jù)。其提供了類(lèi)似于詞典(dictionary-like)的API以及用于聲明可用字段的簡(jiǎn)單語(yǔ)法。

Spider 類(lèi)定義了如何爬取某個(gè)(或某些)網(wǎng)站。包括了爬取的動(dòng)作(例如:是否跟進(jìn)鏈接)以及如何從網(wǎng)頁(yè)的內(nèi)容中提取結(jié)構(gòu)化數(shù)據(jù)(爬取 item)。換句話說(shuō),Spider 就是您定義爬取的動(dòng)作及分析某個(gè)網(wǎng)頁(yè)(或者是有些網(wǎng)頁(yè))的地方。

當(dāng) Item 在 Spider 中被收集之后,它將會(huì)被傳遞到 Item Pipeline,一些組件會(huì)按照一定的順序執(zhí)行對(duì) Item 的處理。

詳情查看官方文檔:http://scrapy-chs.readthedocs.io/zh_CN/1.0/intro/install.html

數(shù)據(jù)庫(kù)

在創(chuàng)建數(shù)據(jù)庫(kù)和新表的過(guò)程中一定要仔細(xì),避免錯(cuò)輸和漏輸,在出現(xiàn)問(wèn)題的時(shí)候一定要認(rèn)真閱讀提示的錯(cuò)誤信息。如果字太小的話可以這么設(shè)置。我電腦的操作系統(tǒng)是Win10。如圖:

把字體調(diào)的大一點(diǎn)看起來(lái)就輕松許多。數(shù)據(jù)庫(kù)命令如果不是很懂可以自行查閱資料,因?yàn)槲乙苍趯W(xué)習(xí)中,先不介紹了太多。

與本文相關(guān)的鏈接

1.http://scrapy-chs.readthedocs.io/zh_CN/1.0/intro/install.html
2.https://www.mysql.com/
3.http://www.itdecent.cn/c/V2CqjW
4.格外感謝這篇教程,受此啟發(fā):Scrapy入門(mén)教程之寫(xiě)入數(shù)據(jù)庫(kù)

如果在操作過(guò)程中遇到問(wèn)題歡迎留言,也可查看:https://alpha87.github.io/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容