天天看點

基于Scrapy的資料分析可視系統 之 資料采集

本系統的這部分内容好像沒什麼好寫的,就不從Scrapy基礎開始說了,挑一些重點部分和容易出錯的地方

來寫一下。其中前程無憂和智聯招聘用的是scrapy,拉勾網因為反爬太強了,用的是selenium,隻能降低采集效率,用的是用selenium模拟登入,并且還得手動輸入驗證碼(九宮格的驗證碼難以識别,找了好幾個平台聯系客服都說無法識别這種,就沒怎麼繼續找了,雖然手動比較low)

1,對與用Scrapy爬取前程無憂和智聯招聘的具體的過程就省略了。我爬的是這兩個招聘網站中的IT崗位資訊,前期沒有設計好,導緻爬蟲數量很多,想要很好的入庫就得用異步插入的方式,因為scrapy是Twisted異步架構,如果使用傳統的pymysql,commit插入方式就很有可能導緻入庫不完整的情況,因為scrapy的采集速度要遠遠大于同步插入的速度,是以,也應該使用異步插入的方式來儲存資料,具體方法如下:

導入twisted:

import MySQLdb
from twisted.enterprise import adbapi
import MySQLdb.cursors      

定義MysqlTwistedPipline類:

class MysqlTwistedPipline(object):
    def __init__(self, dbpool):
        self.dbpool = dbpool

    @classmethod
    def from_settings(cls, settings):
        dbparms = dict(
            host=settings["MYSQL_HOST"],
            db=settings["MYSQL_DBNAME"],
            user=settings["MYSQL_USER"],
            passwd=settings["MYSQL_PASSWORD"],
            charset='utf8',
            cursorclass=MySQLdb.cursors.DictCursor,
            use_unicode=True,
        )
        dbpool = adbapi.ConnectionPool("MySQLdb", **dbparms)

        return cls(dbpool)      

根據不同爬蟲名字來執行不同的插入語句:

def process_item(self, item, spider):
    # 使用twisted将mysql插入變成異步執行
    if spider.name == 'qc_java' or spider.name == 'zl_java':
        query = self.dbpool.runInteraction(self.do_insert_java, item)
        query.addErrback(self.handle_error, item, spider)  # 處理異常
    elif spider.name == 'qc_python' or spider.name == 'zl_python':
        query = self.dbpool.runInteraction(self.do_insert_python, item)
        query.addErrback(self.handle_error, item, spider)
    elif spider.name == 'qc_golang' or spider.name == 'zl_golang':
        query = self.dbpool.runInteraction(self.do_insert_golang, item)
        query.addErrback(self.handle_error, item, spider)
    elif spider.name == 'qc_cplus' or spider.name == 'zl_cplus':
        query = self.dbpool.runInteraction(self.do_insert_cplus, item)
        query.addErrback(self.handle_error, item, spider)
    elif spider.name == 'qc_bigdata' or spider.name == 'zl_bigdata':
        query = self.dbpool.runInteraction(self.do_insert_bigdata, item)
        query.addErrback(self.handle_error, item, spider)
    elif spider.name == 'qc_arithmetic' or spider.name == 'zl_arithmetic':
        query = self.dbpool.runInteraction(self.do_insert_arithmetic, item)
        query.addErrback(self.handle_error, item, spider)
    elif spider.name == 'qc_ai' or spider.name == 'zl_ai':
        query = self.dbpool.runInteraction(self.do_insert_ai, item)

def handle_error(self, failure, item, spider):
    print(failure)      

具體mysql插入語句:

def do_insert_java(self, cursor, item):
    insert_sql = "insert into  `zp_java` (where_from,url,url_obj_id,job_name,company_name,salary_min,salary_max,job_city,experience_year,education_need,publish_date,job_advantage_tags,position_info,job_classification,crawl_time) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"
    item['url_obj_id'] = item['url_obj_id'] + "{0}".format(random.randint(61, 70))
    cursor.execute(insert_sql,
                   (item["where_from"], item["url"], item["url_obj_id"], item["job_name"], item["company_name"], item["salary_min"], item["salary_max"],
                    item["job_city"], item["experience_year"], item["education_need"], item["publish_date"],
                    item["job_advantage_tags"], item["position_info"], item["job_classification"],
                    item["crawl_time"]))      

2,使用Selenium模拟登陸拉鈎代碼:

try:
    self.driver.get(self.login_url)
    self.driver.find_element_by_css_selector("div:nth-child(2) > form > div:nth-child(1) > input").send_keys(
        self.username)
    time.sleep(3)
    self.driver.find_element_by_css_selector("div:nth-child(2) > form > div:nth-child(2) > input").send_keys(
        self.password)
    time.sleep(4)
    self.driver.find_element_by_css_selector(
        "div:nth-child(2) > form > div.input_item.btn_group.clearfix > input").click()
    time.sleep(2)      

   将拉勾網采集的資料一緻遇到一個bug,就是字元串轉義的問題,因為采集的字段有崗位詳情描述,這是一個longtext,裡面夾着一些特殊符号就會才入庫的時候出現報錯,要pymysql.escape_string()就可以很好的解決,這個函數是pymysql自帶的。

效果截圖:

基于Scrapy的資料分析可視系統 之 資料采集