scrapy實戰----將數據存儲到csv文件和MySQL數據庫中

本章將通過爬取51jobs求職網站中的python職位信息來實現不同方式的數據存儲的需求。

github地址———>源代碼

我們先來看一下:51jobs網站
在這裏插入圖片描述
我們需要的數據有,職位名 公司名 工作地點 薪資,這四個數據。
然後我們看一下他們都在哪
發現他們都在
在這裏插入圖片描述
這裏面
在這裏插入圖片描述
需要的數據,相應的都在這裏面
在這裏插入圖片描述
好了到這,我們已經知道了抓取的數據都在哪了。接下來我們開始寫代碼。

創建項目

使用命令scrapy startproject tongscrapy 來創建一個scrapy框架。

然後使用scrapy crawl py51jobs https://search.51job.com/list/000000,000000,0000,00,9,99,python,2,1.html 來創建一個spider項目。

完成這些後打開 pycharm,將創建的項目,添加到pycharm中。

如下圖所示:
在這裏插入圖片描述
然後就是開始重寫各個py文件了。

重寫 py51jobs.py

class Py51jobsSpider(scrapy.Spider):
    name = 'py51jobs'
    #allowed_domains = ['51jobs.com']
    start_urls = ['https://search.51job.com/list/000000,000000,0000,00,9,99,python,2,1.html']

    def parse(self, response):
        item = TongscrapyItem()
        for i in range(4, 45):#每頁共有40條數據
            item['position'] = response.xpath('//*[@id="resultList"]/div[{num}]/p/span/a/text()'.format(num=i), first=True).extract_first().strip()
            item['company'] = response.xpath('//*[@id="resultList"]/div[{num}]/span[1]/a/text()'.format(num=i), first=True).extract_first()
            item['place'] = response.xpath('//*[@id="resultList"]/div[{num}]/span[2]/text()'.format(num=i), first=True).extract_first()
            item['salary'] = response.xpath('//*[@id="resultList"]/div[{num}]/span[3]/text()'.format(num=i), first=True).extract_first()
            print('抓取完畢一條')
            yield item
        for i in range(2, 10): #抓取頁數,可自行更改
            url = 'https://search.51job.com/list/000000,000000,0000,00,9,99,python,2,'+str(i)+'.html'
            yield scrapy.Request(url, callback=self.parse)
            print('抓取完畢一頁')

重寫item.py

class TongscrapyItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    position = scrapy.Field()
    company = scrapy.Field()
    place = scrapy.Field()
    salary = scrapy.Field()

重寫pipelines.py

# 數據存儲在csv文件裏
class savefileTongscrapyPipeline(object):
    def __init__(self):
        self.file = open('py51jobsinfo.csv', 'w', newline='')
        self.csvwriter = csv.writer(self.file)
        self.csvwriter.writerow(['職位名稱', '公司名', '地點', '薪資'])
    def process_item(self, item, spider):
        self.csvwriter.writerow([item["position"], item["company"], item["place"], item["salary"]])
        return item
    def close_spider(self, spider):
        self.file.close()

# 數據存儲在MySQL數據庫裏
class mysqlTongscrapyPipeline(object):
    # 採用異步機制寫入MySQL
    def __init__(self, dppool):
        self.dppool = dppool

    # 用固定方法 【寫法固定】  獲取配置文件內信息
    @classmethod
    def from_settings(cls, settings):  # cls實際就是本類 MysqlTwistedPipeline
        dpparms = dict(
            host=settings["MYSQL_HOST"],
            db=settings["MYSQL_DBNAME"],
            user=settings["MYSQL_USER"],
            passwd=settings["MYSQL_PASSWD"],
            charset="utf8",
            cursorclass=MySQLdb.cursors.DictCursor,  # 指定 curosr 類型  需要導入MySQLdb.cursors
            use_unicode=True
        )
        # 由於要傳遞參數 所以參數名成要與connnect保持一致
        # 用的仍是MySQLdb的庫 twisted並不提供
        # 異步操作
        # adbapi # 可以將MySQLdb的一些操作變成異步化操作
        dppool = adbapi.ConnectionPool("MySQLdb", **dpparms)  # 告訴它使用的是哪個數據庫模塊  連接參數
        # 另外 以上dpparms的參數也可單獨寫,這樣會造成參數列表過大
        return cls(dppool)  # 即實例化一個pipeline

    def process_item(self, item, spider):
        # 使用twisted將mysql插入編程異步操作
        # 指定操作方法和操作的數據 [下面會將方法異步處理]
        query = self.dppool.runInteraction(self.do_insert, item)
        # AttributeError: 'Deferred' object has no attribute 'addErrorback'
        # query.addErrorback(self.handle_error)  # 處理異常
        query.addErrback(self.handle_error)  # 處理異常

    def handle_error(self, failure):
        # 定義錯誤 處理異步插入的異常
        print(failure)

    def do_insert(self, cursor, item):
        """
        此類內其他都可以看作是通用 針對不同的sql操作只需要改寫這裏即可了
        :param cursor:
        :param item:
        :return:
        """
        insert_sql = """insert into py51jobsinfo(position, company, place, salary)
                                    values (%s, %s, %s, %s)"""

        cursor.execute(insert_sql, (item["position"], item["company"], item["place"], item["salary"]))
        return item

最後重寫settings.py,寫入mysql數據庫的配置信息和相應的ITEM_PIPELINES

BOT_NAME = 'tongscrapy'

SPIDER_MODULES = ['tongscrapy.spiders']
NEWSPIDER_MODULE = 'tongscrapy.spiders'
ROBOTSTXT_OBEY = True
ITEM_PIPELINES = {
	#注意後頭的參數是通道運行順序,兩個要不相同,不然會出錯。
   'tongscrapy.pipelines.savefileTongscrapyPipeline': 300,
   'tongscrapy.pipelines.mysqlTongscrapyPipeline': 500,
}
#Mysql數據庫的配置信息
MYSQL_HOST = '192.168.1.106'     #數據庫地址
MYSQL_DBNAME = 'quanluo'         #數據庫名字
MYSQL_USER = 'root'             #數據庫賬號
MYSQL_PASSWD = '123'         #數據庫密碼

MYSQL_PORT = 3306               #數據庫端口

運行py51jobs.py,並輸出結果:

使用代碼:scrapy crawl py51jobs
運行結果爲(展示最後部分):

2020-05-09 23:24:08 [scrapy.core.scraper] DEBUG: Scraped from <200 https://search.51job.com/list/000000,000000,0000,00,9,99,python,2,4.html>
None
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
抓取完畢一頁
2020-05-09 23:24:08 [scrapy.core.engine] INFO: Closing spider (finished)
2020-05-09 23:24:08 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 7745,
 'downloader/request_count': 10,
 'downloader/request_method_count/GET': 10,
 'downloader/response_bytes': 208750,
 'downloader/response_count': 10,
 'downloader/response_status_count/200': 9,
 'downloader/response_status_count/404': 1,
 'dupefilter/filtered': 64,
 'elapsed_time_seconds': 8.845924,
 'finish_reason': 'finished',
 'finish_time': datetime.datetime(2020, 5, 9, 15, 24, 8, 227376),
 'item_scraped_count': 369,
 'log_count/DEBUG': 380,
 'log_count/INFO': 10,
 'request_depth_max': 2,
 'response_received_count': 10,
 'robotstxt/request_count': 1,
 'robotstxt/response_count': 1,
 'robotstxt/response_status_count/404': 1,
 'scheduler/dequeued': 9,
 'scheduler/dequeued/memory': 9,
 'scheduler/enqueued': 9,
 'scheduler/enqueued/memory': 9,
 'start_time': datetime.datetime(2020, 5, 9, 15, 23, 59, 381452)}
2020-05-09 23:24:08 [scrapy.core.engine] INFO: Spider closed (finished)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章