真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

怎么使用PythonScrap框架爬取某食品論壇數(shù)據(jù)

本篇內(nèi)容主要講解“怎么使用Python Scrap框架爬取某食品論壇數(shù)據(jù)”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“怎么使用Python Scrap框架爬取某食品論壇數(shù)據(jù)”吧!

在北碚等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專(zhuān)注、極致的服務(wù)理念,為客戶(hù)提供網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì) 網(wǎng)站設(shè)計(jì)制作按需定制,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),成都品牌網(wǎng)站建設(shè),營(yíng)銷(xiāo)型網(wǎng)站,成都外貿(mào)網(wǎng)站制作,北碚網(wǎng)站建設(shè)費(fèi)用合理。

一、前言

網(wǎng)絡(luò)爬蟲(chóng)(又稱(chēng)為網(wǎng)頁(yè)蜘蛛,網(wǎng)絡(luò)機(jī)器人),是一種按照一定的規(guī)則,自動(dòng)地抓取萬(wàn)維網(wǎng)信息的程序或者腳本。另外一些不常使用的名字還有螞蟻、自動(dòng)索引、模擬程序或者蠕蟲(chóng)。

說(shuō)人話(huà)就是,爬蟲(chóng)是用來(lái)海量規(guī)則化獲取數(shù)據(jù),然后進(jìn)行處理和運(yùn)用,在大數(shù)據(jù)、金融、機(jī)器學(xué)習(xí)等等方面都是必須的支撐條件之一。

目前在一線城市中,爬蟲(chóng)的崗位薪資待遇都是比較客觀的,之后提升到中、高級(jí)爬蟲(chóng)工程師,數(shù)據(jù)分析師、大數(shù)據(jù)開(kāi)發(fā)崗位等,都是很好的過(guò)渡。

二、項(xiàng)目目標(biāo)

本次介紹的項(xiàng)目其實(shí)不用想得太過(guò)復(fù)雜,最終要實(shí)現(xiàn)的目標(biāo)也就是將帖子的每條評(píng)論爬取到數(shù)據(jù)庫(kù)中,并且做到可以更新數(shù)據(jù),防止重復(fù)爬取,反爬等措施。

三、項(xiàng)目準(zhǔn)備

軟件:PyCharm

需要的庫(kù):Scrapy, selenium, pymongo, user_agent,datetime

目標(biāo)網(wǎng)站:

http://bbs.foodmate.net

插件:chromedriver(版本要對(duì))

四、項(xiàng)目分析

1、確定爬取網(wǎng)站的結(jié)構(gòu)

簡(jiǎn)而言之:確定網(wǎng)站的加載方式,怎樣才能正確的一級(jí)一級(jí)的進(jìn)入到帖子中抓取數(shù)據(jù),使用什么格式保存數(shù)據(jù)等。

其次,觀察網(wǎng)站的層級(jí)結(jié)構(gòu),也就是說(shuō),怎么根據(jù)板塊,一點(diǎn)點(diǎn)進(jìn)入到帖子頁(yè)面中,這對(duì)本次爬蟲(chóng)任務(wù)非常重要,也是主要編寫(xiě)代碼的部分。

2、如何選擇合適的方式爬取數(shù)據(jù)?

目前我知道的爬蟲(chóng)方法大概有如下(不全,但是比較常用):

1)request框架:運(yùn)用這個(gè)http庫(kù)可以很靈活的爬取需要的數(shù)據(jù),簡(jiǎn)單但是過(guò)程稍微繁瑣,并且可以配合抓包工具對(duì)數(shù)據(jù)進(jìn)行獲取。但是需要確定headers頭以及相應(yīng)的請(qǐng)求參數(shù),否則無(wú)法獲取數(shù)據(jù);很多app爬取、圖片視頻爬取隨爬隨停,比較輕量靈活,并且高并發(fā)與分布式部署也非常靈活,對(duì)于功能可以更好實(shí)現(xiàn)。

2)scrapy框架:scrapy框架可以說(shuō)是爬蟲(chóng)最常用,最好用的爬蟲(chóng)框架了,優(yōu)點(diǎn)很多:scrapy 是異步的;采取可讀性更強(qiáng)的 xpath 代替正則;強(qiáng)大的統(tǒng)計(jì)和 log 系統(tǒng);同時(shí)在不同的 url 上爬行;支持 shell 方式,方便獨(dú)立調(diào)試;支持寫(xiě) middleware方便寫(xiě)一些統(tǒng)一的過(guò)濾器;可以通過(guò)管道的方式存入數(shù)據(jù)庫(kù)等等。這也是本次文章所要介紹的框架(結(jié)合selenium庫(kù))。

五、項(xiàng)目實(shí)現(xiàn)

1、第一步:確定網(wǎng)站類(lèi)型

首先解釋一下是什么意思,看什么網(wǎng)站,首先要看網(wǎng)站的加載方式,是靜態(tài)加載,還是動(dòng)態(tài)加載(js加載),還是別的方式;根據(jù)不一樣的加載方式需要不同的辦法應(yīng)對(duì)。然后我們觀察今天爬取的網(wǎng)站,發(fā)現(xiàn)這是一個(gè)有年代感的論壇,首先猜測(cè)是靜態(tài)加載的網(wǎng)站;我們開(kāi)啟組織 js 加載的插件,如下圖所示。

怎么使用Python Scrap框架爬取某食品論壇數(shù)據(jù)

刷新之后發(fā)現(xiàn)確實(shí)是靜態(tài)網(wǎng)站(如果可以正常加載基本都是靜態(tài)加載的)。

2、第二步:確定層級(jí)關(guān)系

其次,我們今天要爬取的網(wǎng)站是食品論壇網(wǎng)站,是靜態(tài)加載的網(wǎng)站,在之前分析的時(shí)候已經(jīng)了解了,然后是層級(jí)結(jié)構(gòu):

怎么使用Python Scrap框架爬取某食品論壇數(shù)據(jù)

部分代碼展示:

一級(jí)界面:

def parse(self, response):
    self.logger.info("已進(jìn)入網(wǎng)頁(yè)!")
    self.logger.info("正在獲取版塊列表!")
    column_path_list = response.css('#ct > div.mn > div:nth-child(2) > div')[:-1]
    for column_path in column_path_list:
        col_paths = column_path.css('div > table > tbody > tr > td > div > a').xpath('@href').extract()
        for path in col_paths:
            block_url = response.urljoin(path)
            yield scrapy.Request(
                url=block_url,
                callback=self.get_next_path,

二級(jí)界面:

def get_next_path(self, response):
    self.logger.info("已進(jìn)入版塊!")
    self.logger.info("正在獲取文章列表!")
    if response.url == 'http://www.foodmate.net/know/':
        pass
    else:
        try:
            nums = response.css('#fd_page_bottom > div > label > span::text').extract_first().split(' ')[-2]
        except:
            nums = 1
        for num in range(1, int(nums) + 1):
            tbody_list = response.css('#threadlisttableid > tbody')
            for tbody in tbody_list:
                if 'normalthread' in str(tbody):
                    item = LunTanItem()
                    item['article_url'] = response.urljoin(
                        tbody.css('* > tr > th > a.s.xst').xpath('@href').extract_first())
                    item['type'] = response.css(
                        '#ct > div > div.bm.bml.pbn > div.bm_h.cl > h2 > a::text').extract_first()
                    item['title'] = tbody.css('* > tr > th > a.s.xst::text').extract_first()
                    item['spider_type'] = "論壇"
                    item['source'] = "食品論壇"
                    if item['article_url'] != 'http://bbs.foodmate.net/':
                        yield scrapy.Request(
                            url=item['article_url'],
                            callback=self.get_data,
                            meta={'item': item, 'content_info': []}
                        )
        try:
            callback_url = response.css('#fd_page_bottom > div > a.nxt').xpath('@href').extract_first()
            callback_url = response.urljoin(callback_url)
            yield scrapy.Request(
                url=callback_url,
                callback=self.get_next_path,
            )
        except IndexError:
            pass

三級(jí)界面:

def get_data(self, response):
    self.logger.info("正在爬取論壇數(shù)據(jù)!")
    item = response.meta['item']
    content_list = []
    divs = response.xpath('//*[@id="postlist"]/div')
    user_name = response.css('div > div.pi > div:nth-child(1) > a::text').extract()
    publish_time = response.css('div.authi > em::text').extract()
    floor = divs.css('* strong> a> em::text').extract()
    s_id = divs.xpath('@id').extract()
    for i in range(len(divs) - 1):
        content = ''
        try:


            strong = response.css('#postmessage_' + s_id[i].split('_')[-1] + '').xpath('string(.)').extract()
            for s in strong:
                content += s.split(';')[-1].lstrip('\r\n')
            datas = dict(content=content,  # 內(nèi)容
                         reply_id=0,  # 回復(fù)的樓層,默認(rèn)0
                         user_name=user_name[i],  # ?戶(hù)名
                         publish_time=publish_time[i].split('于 ')[-1],  # %Y-%m-%d %H:%M:%S'
                         id='#' + floor[i],  # 樓層
                         )
            content_list.append(datas)
        except IndexError:
            pass
    item['content_info'] = response.meta['content_info']
    item['scrawl_time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    item['content_info'] += content_list


    data_url = response.css('#ct > div.pgbtn > a').xpath('@href').extract_first()
    if data_url != None:
        data_url = response.urljoin(data_url)
        yield scrapy.Request(
            url=data_url,
            callback=self.get_data,
            meta={'item': item, 'content_info': item['content_info']}
        )
    else:
        item['scrawl_time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        self.logger.info("正在存儲(chǔ)!")
        print('儲(chǔ)存成功')
        yield item

3、第三步:確定爬取方法

由于是靜態(tài)網(wǎng)頁(yè),首先決定采用的是scrapy框架直接獲取數(shù)據(jù),并且通過(guò)前期測(cè)試發(fā)現(xiàn)方法確實(shí)可行,不過(guò)當(dāng)時(shí)年少輕狂,小看了網(wǎng)站的保護(hù)措施,由于耐心有限,沒(méi)有加上定時(shí)器限制爬取速度,導(dǎo)致我被網(wǎng)站加了限制,并且網(wǎng)站由靜態(tài)加載網(wǎng)頁(yè)變?yōu)椋簞?dòng)態(tài)加載網(wǎng)頁(yè)驗(yàn)證算法之后再進(jìn)入到該網(wǎng)頁(yè),直接訪問(wèn)會(huì)被后臺(tái)拒絕。

但是這種問(wèn)題怎么會(huì)難道我這小聰明,經(jīng)過(guò)我短暫地思考(1天),我將方案改為scrapy框架 + selenium庫(kù)的方法,通過(guò)調(diào)用chromedriver,模擬訪問(wèn)網(wǎng)站,等網(wǎng)站加載完了再爬取不就完了,后續(xù)證明這個(gè)方法確實(shí)可行,并且效率也不錯(cuò)。

實(shí)現(xiàn)部分代碼如下:

def process_request(self, request, spider):
    chrome_options = Options()
    chrome_options.add_argument('--headless')  # 使用無(wú)頭谷歌瀏覽器模式
    chrome_options.add_argument('--disable-gpu')
    chrome_options.add_argument('--no-sandbox')
    # 指定谷歌瀏覽器路徑
    self.driver = webdriver.Chrome(chrome_options=chrome_options,
                                   executable_path='E:/pycharm/workspace/爬蟲(chóng)/scrapy/chromedriver')
    if request.url != 'http://bbs.foodmate.net/':
        self.driver.get(request.url)
        html = self.driver.page_source
        time.sleep(1)
        self.driver.quit()
        return scrapy.http.HtmlResponse(url=request.url, body=html.encode('utf-8'), encoding='utf-8',
                                        request=request)

4、第四步:確定爬取數(shù)據(jù)的儲(chǔ)存格式

這部分不用多說(shuō),根據(jù)自己需求,將需要爬取的數(shù)據(jù)格式設(shè)置在items.py中。在工程中引用該格式保存即可:

class LunTanItem(scrapy.Item):
    """
        論壇字段
    """
    title = Field()  # str: 字符類(lèi)型 | 論壇標(biāo)題
    content_info = Field()  # str: list類(lèi)型 | 類(lèi)型list: [LunTanContentInfoItem1, LunTanContentInfoItem2]
    article_url = Field()  # str: url | 文章鏈接
    scrawl_time = Field()  # str: 時(shí)間格式 參照如下格式 2019-08-01 10:20:00 | 數(shù)據(jù)爬取時(shí)間
    source = Field()  # str: 字符類(lèi)型 | 論壇名稱(chēng) eg: 未名BBS, 水木社區(qū), 天涯論壇
    type = Field()  # str: 字符類(lèi)型 | 板塊類(lèi)型 eg: '財(cái)經(jīng)', '體育', '社會(huì)'
    spider_type = Field()  # str: forum | 只能寫(xiě) 'forum'

5、第五步:確定保存數(shù)據(jù)庫(kù)

本次項(xiàng)目選擇保存的數(shù)據(jù)庫(kù)為MongoDB,由于是非關(guān)系型數(shù)據(jù)庫(kù),優(yōu)點(diǎn)顯而易見(jiàn),對(duì)格式要求沒(méi)有那么高,可以靈活儲(chǔ)存多維數(shù)據(jù),一般是爬蟲(chóng)優(yōu)選數(shù)據(jù)庫(kù)(不要和我說(shuō)redis,會(huì)了我也用,主要是不會(huì))

代碼:

import pymongo


class FMPipeline():
    def __init__(self):
        super(FMPipeline, self).__init__()
        # client = pymongo.MongoClient('139.217.92.75')
        client = pymongo.MongoClient('localhost')
        db = client.scrapy_FM
        self.collection = db.FM


    def process_item(self, item, spider):
        query = {
            'article_url': item['article_url']
        }
        self.collection.update_one(query, {"$set": dict(item)}, upsert=True)
m

這時(shí),有聰明的盆友就會(huì)問(wèn):如果運(yùn)行兩次爬取到了一樣的數(shù)據(jù)怎么辦呢?(換句話(huà)說(shuō)就是查重功能)

這個(gè)問(wèn)題之前我也沒(méi)有考慮,后來(lái)在我詢(xún)問(wèn)大佬的過(guò)程中知道了,在我們存數(shù)據(jù)的時(shí)候就已經(jīng)做完這件事了,就是這句:

query = {
    'article_url': item['article_url']
}
self.collection.update_one(query, {"$set": dict(item)}, upsert=True)

通過(guò)帖子的鏈接確定是否有數(shù)據(jù)爬取重復(fù),如果重復(fù)可以理解為將其覆蓋,這樣也可以做到更新數(shù)據(jù)。

6、其他設(shè)置

像多線程、headers頭,管道傳輸順序等問(wèn)題,都在settings.py文件中設(shè)置,具體可以參考小編的項(xiàng)目去看,這里不再贅述。

七、效果展示

1、點(diǎn)擊運(yùn)行,結(jié)果顯示在控制臺(tái),如下圖所示。

怎么使用Python Scrap框架爬取某食品論壇數(shù)據(jù)

2、中間會(huì)一直向隊(duì)列中堆很多帖子的爬取任務(wù),然后多線程處理,我設(shè)置的是16線程,速度還是很可觀的。

怎么使用Python Scrap框架爬取某食品論壇數(shù)據(jù)

content_info中存放著每個(gè)帖子的全部留言以及相關(guān)用戶(hù)的公開(kāi)信息。

到此,相信大家對(duì)“怎么使用Python Scrap框架爬取某食品論壇數(shù)據(jù)”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢(xún),關(guān)注我們,繼續(xù)學(xué)習(xí)!


名稱(chēng)欄目:怎么使用PythonScrap框架爬取某食品論壇數(shù)據(jù)
本文路徑:http://weahome.cn/article/ggdppd.html

其他資訊

在線咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部