九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
程序員如何煉成 Python 爬蟲“王者”?
本文章精選了五個爬蟲實例,希望能夠給想要入門 Python 爬蟲的小伙伴兒們一些幫助。

網(wǎng)易精選評價爬取

首先來看一個網(wǎng)易精選網(wǎng)站的爬蟲例子,可以爬取評價的商品很多,這里選擇“iPhone”關(guān)鍵字為例子,因為此類商品種類、樣式、顏色等比較多,利于后面的數(shù)據(jù)分析。
分析網(wǎng)頁
評論分析
進入到網(wǎng)易精選官網(wǎng),搜索“iPhone”后,先隨便點進一個商品。

在商品頁面,打開 Chrome 的控制臺,切換至 Network 頁,再把商品頁面切換到評價標(biāo)簽下,選擇一個評論文字,如“手機套很薄,裸機的手感”,在 Network 中搜索。

可以發(fā)現(xiàn),評論文字是通過 listByItemByTag.json 傳遞過來的,點擊進入該請求,并拷貝出該請求的 URL:

將該 URL 放入 Postman 中,逐個嘗試 url query params,最后能夠發(fā)現(xiàn),只需保留 itemId 和 page 兩個請求參數(shù)即可。

請求返回的是一個 JSON 格式的數(shù)據(jù),下面就是分析該 JSON 數(shù)據(jù)了。
不難發(fā)現(xiàn),所有的評論數(shù)據(jù)都存儲在 commentList 中,我們只需保存該數(shù)據(jù)即可。
下面就是如何獲取 itemId 的信息了,這個是產(chǎn)品的 ID,我們回到網(wǎng)易精選首頁,繼續(xù)分析。
產(chǎn)品 ID 獲取
當(dāng)我們在搜索框中輸入關(guān)鍵字進行搜索的時候,同樣能夠發(fā)現(xiàn)在 Network 中有很多請求,此時可以觀察各個請求,通過請求文件的名稱(此處需要一些經(jīng)驗,守規(guī)矩的程序員都不會亂起名字),我們可以定位到搜索時展示搜索結(jié)果的請求。

搜索一般都是 search,所以我們就鎖定了這個 search.json 的請求。同樣把請求 URL 拷貝到 Postman 中,逐個驗證傳參,最后保留 page 和 keyword 兩個參數(shù)即可。

該請求返回的數(shù)據(jù)較多,還是需要耐心的分析數(shù)據(jù),也能夠發(fā)現(xiàn),在 result->data->directly->searcherResult->result 下面的 id 值,即為我們要獲取的產(chǎn)品 ID。
以上,我們基本完成了前期的分析工作,下面開始代碼的編寫。
編寫代碼
獲取產(chǎn)品 ID
Python
def search_keyword(keyword):
    uri = 'https://you.163.com/xhr/search/search.json'
    query = {
        'keyword': keyword,
        'page'1
    }
    try:
        res = requests.get(uri, params=query).json()
        result = res['data']['directly']['searcherResult']['result']
        product_id = []
        for r in result:
            product_id.append(r['id'])
        return product_id
    except:
        raise

我這里是獲取了 page 為 1 的產(chǎn)品 ID,下面就是通過產(chǎn)品 ID 來獲取不同產(chǎn)品下的評論信息。

通過前面的分析,我們可以知道,評論信息都是如下形式的,對這種形式的信息,我們可以很方便地存儲進入 MongoDB,然后再慢慢分析數(shù)據(jù)里的內(nèi)容。
{
                'skuInfo': [
                    '機型:iphone X',
                    '顏色:透明白'
                ],
                'frontUserName''c****x',
                'frontUserAvatar''https://yanxuan.nosdn.127.net/c230f2c2a6e7223810755518ce5cd62f',
                'content''手機套很薄,裸機的手感,硅膠的摸著好舒服,看著屏幕都變大了。顏值很高。',
                'createTime'1554982110981,
                'picList': [
                    'https://yanxuan.nosdn.127.net/749cfcb4877be8e7fce449900d763731.jpg',
                    'https://yanxuan.nosdn.127.net/6744d04efcd7509556b710bc0d9fa6b0.jpg'
                ],
                'commentReplyVO'null,
                'memberLevel'4,
                'appendCommentVO'null,
                'star'5,
                'itemId'3444035
            }
對于 MongoDB,我們既可以自己搭建,也可以使用網(wǎng)上免費的服務(wù)。在這里我介紹一個免費的 MongoDB 服務(wù)網(wǎng)站:mlab,使用很簡單,就不過多介紹使用過程了。
數(shù)據(jù)庫有了,下面就是把數(shù)據(jù)保存進去了。
def details(product_id):
    url = 'https://you.163.com/xhr/comment/listByItemByTag.json'
    try:
        C_list = []
        for i in range(1100):
            query = {
                'itemId': product_id,
                'page': i,
            }
            res = requests.get(url, params=query).json()
            if not res['data']['commentList']:
                break
            print('爬取第 %s 頁評論' % i)
            commentList = res['data']['commentList']
            C_list.append(commentList)
            time.sleep(1)
            # save to mongoDB
            try:
                mongo_collection.insert_many(commentList)
            except:
                continue
        return C_list
    except:
        raise
在這里,details 這個函數(shù)還返回了評論的列表,如果你還有其他的邏輯需要對評論處理,可以接收這個函數(shù)的返回值,然后處理該列表。
最后爬取完成之后,總共是七千多條數(shù)據(jù),下面就可以根據(jù)個人需要做一些分析了。

完整代碼地址:https://github.com/zhouwei713/dataanalysis/tree/master/you163spider。
爬取的數(shù)據(jù) MongoDB 鏈接:
conn = MongoClient('mongodb://%s:%s@ds149974.mlab.com:49974/you163' % ('you163''you163'))
db = conn.you163
mongo_collection = db.iPhone

Boss 直聘網(wǎng)站爬取


其實分析的步驟都是類似的,無外乎是先分析網(wǎng)站信息,頁面組成,然后編寫代碼爬取數(shù)據(jù),最后再保存數(shù)據(jù)。
頁面分析
我們選取一個崗位來分析,比如:Python。
在 Boss 直聘的官網(wǎng)上搜索 Python,可以看到瀏覽器的 URL 變?yōu)槿缦拢?/span>

把該地址復(fù)制到 Postman 嘗試訪問,發(fā)現(xiàn)無法得到正確的返回:

此時,再次回到瀏覽器,查看該請求下面的 headers,可以看到其中有一個 cookie,是很長的一串字符串,我們拷貝這個 cookie 到 Postman 中,再次請求:

成功了,看來 Boss 直聘網(wǎng)也只是做了簡單的 cookies 驗證。
BeautifulSoup 使用
下面就是解析 HTML 數(shù)據(jù)了,我比較習(xí)慣用 BeautifulSoup 這個庫來解析。
from bs4 import BeautifulSoup
import requests

url = 'https://www.zhipin.com/job_detail/?query=python&city=101010100'

res = requests.get(url, headers=header).text
print(res)
content = BeautifulSoup(res, 'html.parser')
ul = content.find_all('ul')
print(ul[12])
可以使用 BeautifulSoup 的 find 函數(shù)來查找 HTML 的元素標(biāo)簽,個人覺得還是挺方便的。
編寫代碼
我們通過分析 HTML 網(wǎng)頁可以知道,所有的工作信息都是保存在 ul 這個標(biāo)簽中的,我們可以通過上面的代碼拿到頁面中所有的 ul 標(biāo)簽,find_all 返回的是一個列表,然后再查看,工作具體位于第幾個 ul 中,這樣就拿到具體的工作信息了。
確定需要抓取的數(shù)據(jù)

如圖中所示,我們需要抓取紅框中的信息,主要分為四部分。
  • Python:可以得到該 job 具體頁面地址

  • 10-15K:每個 job 的薪資

  • 柯萊特集團:招聘公司名稱

  • 北京 朝陽區(qū) 望京|3-5年|學(xué)歷不限:該 job 的詳情信息

對于前三個信息,還是比較好抓取的。
job_details_uri = job.find('h3', attrs={'class''name'}).find('a')['href']
job_company = job.find('div', attrs={'class''company-text'}).find('h3', attrs={'class''name'}).find('a').text
job_salary = job.find('h3', attrs={'class''name'}).find('span', attrs={'class''red'}).text
對于 job 的詳情信息,需要用到正則表達(dá)式來分割字符串,我們先來看下該部分的原始形式:

又可以把該部分切分成三塊,site、year 和 edu??梢允褂谜齽t的 group 特性,幫助我們完成切分,最后我寫的正則如下:
rege = r'<p>([\u4e00-\u9fa5 ]+)<em class='vline'></em>([\d+-年]+|[\u4e00-\u9fa5]+)<em class='vline'></em>([\u4e00-\u9fa5]+)'

正則表達(dá)式的具體寫法這里就不說了,不熟悉的可以自行查找下。

下面把這部分代碼整合到一起:
for job in jobs:
    job_dict = {}
    job_details_uri = job.find('h3', attrs={'class''name'}).find('a')['href']
    job_company = job.find('div', attrs={'class''company-text'}).find('h3', attrs={'class''name'}).find('a').text
    job_salary = job.find('h3', attrs={'class''name'}).find('span', attrs={'class''red'}).text
    job_details = str(job.find('p'))
    print(job_details)
    job_rege = re.match(rege, job_details)
    job_dict['name'] = job_company
    job_dict['uri'] = job_details_uri
    job_dict['salary'] = job_salary
    job_dict['site'] = job_rege.group(1)
    job_dict['year'] = job_rege.group(2)
    job_dict['edu'] = job_rege.group(3)
    job_list.append(job_dict)
print(job_list)
由于我們最后還是得到了一個列表,里面包含字典,同樣可以快捷的保存到 MongoDB 中。
抓取多個頁面
通過查看 Boss 網(wǎng)站的下一頁源碼可得到翻頁 URL 的規(guī)律:
https://www.zhipin.com/c101010100/?query=python&page=
  • c101010100:是城市代碼,在我們這里就代表北京

  • query:也很明顯,就是我們的搜索關(guān)鍵字

  • page:頁數(shù)

于是我們最后整合代碼如下:
def jobs(page):

    for i in range(1, page + 1):
        job_list = []
        try:
            print('正在抓取第 %s 頁數(shù)據(jù)' % i)
            uri = '/c101010100/?query=python&page=%s' % i
            res = requests.get(config.url + uri, headers=header).text
            content = BeautifulSoup(res, 'html.parser')
            ul = content.find_all('ul')
            jobs = ul[12].find_all('li')
            ...
            print(job_list)

            # save to mongoDB
            try:
                mongo_collection.insert_many(job_list)
            except:
                continue
            time.sleep(1)
        except:
            continue
因為我上面的正在表達(dá)式并不能匹配所有的情況,所以使用 try...except 來忽略了其他不規(guī)則的情況。
崗位詳情抓取
job 詳情抓取完畢之后,開始抓取崗位詳情,就是每個 job 的具體要求,畢竟知己知彼,百戰(zhàn)不殆。
我們可以從 URI 中獲得每個工作的詳情頁面地址,然后再拼接到 Boss 的主 URL 上:
https://www.zhipin.com/job_detail/a8920821a7487a901HJ43tm7EFY~.html
再來看下工作詳情頁面,所有的任職描述都在如下的 div 標(biāo)簽中:
沒有什么特殊的,直接用 BeautifulSoup 解析即可。
job_conn = MongoClient('mongodb://%s:%s@ds151612.mlab.com:51612/boss' % ('boss''boss123'))
job_db = job_conn.boss
job_collection = job_db.boss

details_collection = job_db.job_details


def run_main():
    jobs = job_collection.find()
    for job in jobs:
        print('獲得工作的uri ', job['uri'])
        get_details(job)
        time.sleep(1)


def get_details(items):
    base_url = config.url
    url = base_url + items['uri']
    company_name = items['name']
    try:
        res = requests.get(url, headers=header).text
        content = BeautifulSoup(res, 'html.parser')
        text = content.find('div', attrs={'class''text'}).text.strip()
        result = {'name': company_name, 'details': text}
        details_collection.insert_one(result)
    except:
        raise 


if __name__ == '__main__':
    run_main()
注意下這里的 MongoDB 配置,是同一個 db 下的不同 collection。這樣,也就完成了直聘網(wǎng)站相關(guān)崗位的數(shù)據(jù)爬取。
完整代碼地址:https://github.com/zhouwei713/dataanalysis/tree/master/bossspider。
爬取的數(shù)據(jù) MongoDB 鏈接:
job_conn = MongoClient('mongodb://%s:%s@ds151612.mlab.com:51612/boss' % ('boss''boss123'))
job_db = job_conn.boss
job_collection = job_db.boss
details_collection = job_db.job_details

微博爬取

這里的微博爬蟲,我主要實現(xiàn)的是輸入你關(guān)心的某個大 V 的微博名稱,以及某條微博的相關(guān)內(nèi)容片段,即可自動爬取相關(guān)該大 V 一段時間內(nèi)發(fā)布的微博信息和對應(yīng)微博的評論信息。
Cookie 獲取
與上面的 Boss 直聘網(wǎng)站類似,爬取微博也需要獲取響應(yīng)的 cookie。

用瀏覽器打開微博頁面,拷貝出對應(yīng)的 Cookie,保存到本地。
微博搜索
既然是某位大 V,這里就肯定涉及到了搜索的事情,我們可以先來嘗試下微博自帶的搜索,地址如下:
s.weibo.com/user?q=林志玲
同樣是先放到 Postman 里請求下,看看能不能直接訪問:

是可以的,這就省去了我們很多的麻煩。下面就是來分析并解析響應(yīng)消息,拿到對我們有用的數(shù)據(jù)。
經(jīng)過觀察可知,這個接口返回的數(shù)據(jù)中,有一個 UID 信息,是每個微博用戶的唯一 ID,我們可以拿過來留作后面使用。

至于要如何定位到這個 UID,我也已經(jīng)在圖中做了標(biāo)注,相信你只要簡單分析下就能明白。
def get_uid(name):
    try:
        url = 'https://s.weibo.com/user?q=%s' % name
        res = requests.get(url).text
        content = BeautifulSoup(res, 'html.parser')
        user = content.find('div', attrs={'class''card card-user-b s-pg16 s-brt1'})
        user_info = user.find('div', attrs={'class''info'}).find('div')
        href_list = user_info.find_all('a')
        if len(href_list) == 3:
            title = href_list[1].get('title')
            if title == '微博個人認(rèn)證':
                uid = href_list[2].get('uid')
                return uid
            elif title == '微博會員':
                uid = href_list[2].get('uid')
                return uid
        else:
            print('There are something wrong')
            return False
    except:
        raise
還是通過 BeautifulSoup 來定位獲取元素,最后返回 UID 信息。
M 站的利用
M 站一般是指手機網(wǎng)頁端的頁面,也就是為了適配 mobile 移動端而制作的頁面。一般的網(wǎng)站都是在原網(wǎng)址前面加“m.”來作為自己 M 站的地址,比如:m.baidu.com 就是百度的 M 站。
我們來打開微博的 M 站,再進入到林志玲的微博頁面看看 Network 中的請求,有沒有什么驚喜呢?
我們首先發(fā)現(xiàn)了這樣一個 URL:
https://m.weibo.cn/api/container/getIndex?uid=1312412824&luicode=10000011&lfid=100103type%3D1%26q%3D%E6%9E%97%E5%BF%97%E7%8E%B2&containerid=1005051312412824
接著繼續(xù)拖動網(wǎng)頁,發(fā)現(xiàn) Network 中又有類似的 URL:
https://m.weibo.cn/api/container/getIndex?uid=1312412824&luicode=10000011&lfid=100103type%3D1%26q%3D%E6%9E%97%E5%BF%97%E7%8E%B2&containerid=1076031312412824
URL 類似,但是第一個返回的數(shù)據(jù)是用戶信息,而第二個返回的則是用戶的微博信息,顯然第二個 URL 是我們需要的。同樣道理,把第二個 URL 放到 Postman 中,看看哪些參數(shù)是可以省略的。

最后我們發(fā)現(xiàn),只要傳入正確的 containerid 信息,就能夠返回對應(yīng)的微博信息,可是 containerid 信息又從哪里來呢?我們剛剛獲得了一個 UID 信息,現(xiàn)在來嘗試下能不能通過這個 UID 來獲取到 containerid 信息。
這里就又需要一些經(jīng)驗了,我可以不停的嘗試給接口“m.weibo.cn/api/container/getIndex”添加不同的參數(shù),看看它會返回些什么信息,比如常見的參數(shù)名稱 type、id、value、name 等。最終,在我不懈的努力下,發(fā)現(xiàn) type 和 value 的組合是成功的,可以拿到對應(yīng)的 containerid 信息。

這個地方真的不有任何捷徑了,只能靠嘗試和經(jīng)驗。
現(xiàn)在就可以編寫代碼,獲取對應(yīng)的 containerid 了(如果你細(xì)心的話,還可以看到這個接口還返回了很多有意思的信息,可以自己嘗試著抓?。?。
def get_userinfo(uid):
    try:
        url = 'https://m.weibo.cn/api/container/getIndex?type=uid&value=%s' % uid
        res = requests.get(url).json()
        containerid = res['data']['tabsInfo']['tabs'][1]['containerid']
        mblog_counts = res['data']['userInfo']['statuses_count']
        followers_count = res['data']['userInfo']['followers_count']
        userinfo = {
            'containerid': containerid,
            'mblog_counts': mblog_counts,
            'followers_count': followers_count
        }
        return userinfo
    except:
        raise
代碼里都是基本操作,不過多解釋了。
拿到 containerid 信息之后,我們就可以使用上面第二個 URL 來獲取微博信息了,這里還是同樣的問題——分頁。怎么處理分頁呢,繼續(xù)改造這個 getIndex 接口,繼續(xù)嘗試傳遞不同的參數(shù)給它。
這次給它傳遞 containerid 和 page 信息,就可以完成分頁請求了。

傳遞的 page 為 3 時,其實是獲取當(dāng)前新浪微博的第 4 頁數(shù)據(jù),后面我們就可以用這個 URL 來獲取微博信息了。
該接口返回的是 JSON 數(shù)據(jù),解析起來就比較方便了。
微博信息就保存在 res['data']['cards'] 下面,有評論、轉(zhuǎn)發(fā)、點贊數(shù)量等信息。于是我們解析該 JSON 數(shù)據(jù)的函數(shù)就有了:
def get_blog_info(cards, i, name, page):
    blog_dict = {}
    if cards[i]['card_type'] == 9:
        scheme = cards[i]['scheme']  # 微博地址
        mblog = cards[i]['mblog']
        mblog_text = mblog['text']
        create_time = mblog['created_at']
        mblog_id = mblog['id']
        reposts_count = mblog['reposts_count']  # 轉(zhuǎn)發(fā)數(shù)量
        comments_count = mblog['comments_count']  # 評論數(shù)量
        attitudes_count = mblog['attitudes_count']  # 點贊數(shù)量
        with open(name, 'a', encoding='utf-8'as f:
            f.write('----第' + str(page) + '頁,第' + str(i + 1) + '條微博----' + '\n')
            f.write('微博地址:' + str(scheme) + '\n' + '發(fā)布時間:' + str(create_time) + '\n'
                    + '微博內(nèi)容:' + mblog_text + '\n' + '點贊數(shù):' + str(attitudes_count) + '\n'
                    + '評論數(shù):' + str(comments_count) + '\n' + '轉(zhuǎn)發(fā)數(shù):' + str(reposts_count) + '\n')
        blog_dict['mblog_id'] = mblog_id
        blog_dict['mblog_text'] = mblog_text
        blog_dict['create_time'] = create_time
        return blog_dict
    else:
        print('沒有任何微博哦')
        return False
函數(shù)參數(shù):
  • 第一個參數(shù),接受的值為 res['data']['cards'] 的返回值,是一個字典類型數(shù)據(jù);

  • 第二個參數(shù),是外層調(diào)用函數(shù)的循環(huán)計數(shù)器;

  • 第三個參數(shù),是要爬取的大 V 名稱;

  • 第四個參數(shù),是正在爬取的頁碼。

最后函數(shù)返回一個字典。
搜索微博信息
我們還要實現(xiàn)通過微博的一些字段,來定位到某個微博,從而抓取該微博下的評論的功能。
再定義一個函數(shù),調(diào)用上面的 get_blog_info 函數(shù),從其返回的字典中拿到對應(yīng)的微博信息,再和需要比對的我們輸入的微博字段做比較,如果包含,那么就說明找到我們要的微博啦。
def get_blog_by_text(containerid, blog_text, name):
    blog_list = []
    page = 1
    while True:
        try:
            url = 'https://m.weibo.cn/api/container/getIndex?containerid=%s&page=%s' % (containerid, page)
            res_code = requests.get(url).status_code
            if res_code == 418:
                print('訪問太頻繁,過會再試試吧')
                return False
            res = requests.get(url).json()
            cards = res['data']['cards']
            if len(cards) > 0:
                for i in range(len(cards)):
                    print('-----正在爬取第' + str(page) + '頁,第' + str(i+1) + '條微博------')
                    blog_dict = get_blog_info(cards, i, name, page)
                    blog_list.append(blog_dict)
                    if blog_list is False:
                        break
                    mblog_text = blog_dict['mblog_text']
                    create_time = blog_dict['create_time']
                    if blog_text in mblog_text:
                        print('找到相關(guān)微博')
                        return blog_dict['mblog_id']
                    elif checkTime(create_time, config.day) is False:
                        print('沒有找到相關(guān)微博')
                        return blog_list
                page += 1
                time.sleep(config.sleep_time)
            else:
                print('沒有任何微博哦')
                break

        except:
            pass
這里調(diào)用了一個工具函數(shù) checkTime 和一個配置文件 config。
checkTime 函數(shù)定義如下:
def checkTime(inputtime, day):
    try:
        intime = datetime.datetime.strptime('2019-' + inputtime, '%Y-%m-%d')
    except:
        return '時間轉(zhuǎn)換失敗'

    now = datetime.datetime.now()
    n_days = now - intime
    days = n_days.days
    if days < day:
        return True
    else:
        return False
定義這個函數(shù)的目的是為了限制搜索時間,比如對于 90 天以前的微博,就不再搜索了,也是提高效率。
而 config 配置文件里,則定義了一個配置項 day,來控制可以搜索的時間范圍:
day = 90  # 最久抓取的微博時間,60即為只抓取兩個月前到現(xiàn)在的微博
sleep_time = 5  # 延遲時間,建議配置5-10s
獲取評論信息
對于微博評論信息的獲取,要簡單很多。
我們進入某一個微博頁面,進入到評論區(qū):
https://weibo.com/1312412824/HxFY84Gqb?filter=hot&root_comment_id=0&type=comment#_rnd1567155548217


從 Network 中可以拿到一個請求 URL:
https://weibo.com/aj/v6/comment/big?ajwvr=6&id=4380261561116383&from=singleWeiBo&__rnd=1567155729639
同樣使用 Postman 進行 URL 精簡和分頁處理,可以得到最后的 URL 為:
https://weibo.com/aj/v6/comment/big?ajwvr=6&id=%s&page=%s
  • id 就是要抓取評論的微博對應(yīng)的 id,我們已經(jīng)在上面的接口中拿到了;

  • page 就是請求頁數(shù)。

獲取評論及保存數(shù)據(jù)代碼:
def get_comment(self, mblog_id, page):
    comment = []
    for i in range(0, page):
        print('-----正在爬取第' + str(i) + '頁評論')
        url = 'https://weibo.com/aj/v6/comment/big?ajwvr=6&id=%s&page=%s' % (mblog_id, i)
        req = requests.get(url, headers=self.headers).text
        html = json.loads(req)['data']['html']
        content = BeautifulSoup(html, 'html.parser')
        comment_text = content.find_all('div', attrs={'class''WB_text'})
        for c in comment_text:
            _text = c.text.split(':')[1]
            comment.append(_text)
        time.sleep(config.sleep_time)

    return comment

def download_comment(self, comment):
    comment_pd = pd.DataFrame(columns=['comment'], data=comment)
    timestamp = str(int(time.time()))
    comment_pd.to_csv(timestamp + 'comment.csv', encoding='utf-8')
定義運行函數(shù)
最后,我們開始定義運行函數(shù),把需要用戶輸入的相關(guān)信息都從運行函數(shù)中獲取并傳遞給后面的邏輯函數(shù)中。
from weibo_spider import WeiBo
from config import headers


def main(name, spider_type, text, page, iscomment, comment_page):
    print('開始...')
    weibo = WeiBo(name, headers)
    ...


if __name__ == '__main__':
    target_name = input('type the name: ')
    spider_type = input('type spider type(Text or Page): ')
    text = '你好'
    page_count = 10
    iscomment = 'No'
    comment_page_count = 100
    while spider_type not in ('Text''text''Page''page'):
        spider_type = input('type spider type(Text or Page): ')
    ...
通過 input 函數(shù)接受用戶輸入信息,再判斷程序執(zhí)行。
爬蟲類與工具集
最后再來看下程序中的 WeiBo 爬蟲類的定義:
class WeiBo(object):

    def __init__(self, name, headers):
        self.name = name
        self.headers = headers

    def get_uid(self):  # 獲取用戶的 UID
        ...

    def get_userinfo(self, uid):  # 獲取用戶信息,包括 containerid
        ...

    def get_blog_by_page(self, containerid, page, name):  # 獲取 page 頁的微博信息
        ...

    def get_blog_by_text(self, containerid, blog_text, name):  # 一個簡單的搜索功能,根據(jù)輸入的內(nèi)容查找對應(yīng)的微博
        ...

    def get_comment(self, mblog_id, page):  # 與上個函數(shù)配合使用,用于獲取某個微博的評論
        ...

    def download_comment(self, comment):  # 下載評論
        ...
在類的初始化函數(shù)中,傳入需要爬取的大 V 名稱和我們準(zhǔn)備好的 headers(cookie),然后把上面寫好的函數(shù)寫道該類下,后面該類的實例 weibo 就能夠調(diào)用這些函數(shù)了。
對于工具集,就是抽象出來的一些邏輯處理:
import datetime
from config import day


def checkTime(inputtime, day):
    ...


def get_blog_info(cards, i, name, page):
    ...
最終程序運行示例:

完整代碼地址:https://github.com/zhouwei713/weibo_spider。

女神大會數(shù)據(jù)爬取

繼續(xù)爬取懂球帝的女神大會數(shù)據(jù)。
頁面 ID 信息獲取
不過這里有一個問題,以前的懂球帝是帶有搜索功能的,所以我們能從搜索功能中找到一個用于搜索的 API,但是現(xiàn)在該功能不見了,所以這里已經(jīng)沒有辦法展示如何拿到搜索 API 的過程了。
但是搜索 API 我們還是可以使用的:
http://api.dongqiudi.com/search?keywords=&type=all&page=
我們可以通過給 keyword 傳入“女神大會”關(guān)鍵字,來獲取到女神大會相關(guān)的信息:

  • id 是對應(yīng)的每個網(wǎng)頁的 id;

  • thumb 是女神的封面圖片;

  • url 對應(yīng)的也是女神所在頁面的地址信息。

于是,我們可以通過輸入不同的 page 數(shù)值,獲取到所有的 JSON 信息,并解析 JSON,保存我們需要的數(shù)據(jù):
def get_list(page):
    nvshen_id_list = []
    nvshen_id_picture = []
    for i in range(1, page):
        print('獲取第' + str(i) + '頁數(shù)據(jù)')
        url = 'http://api.dongqiudi.com/search?keywords=%E5%A5%B3%E7%A5%9E%E5%A4%A7%E4%BC%9A&type=all&page=' + str(i)
        html = requests.get(url=url).text
        news = json.loads(html)['news']
        if len(news) == 0:
            print('沒有更多啦')
            break
        nvshen_id = [k['id'for k in news]
        nvshen_id_list = nvshen_id_list + nvshen_id
        nvshen_id_picture = nvshen_id_picture + [{k['id']: k['thumb']} for k in news]
        time.sleep(1)
    return nvshen_id_list, nvshen_id_picture
下載 HTML 頁面
我們把上面 API 拿到的 url 字段放到懂球帝的主地址下,拼接成如下 url:
http://www.dongqiudi.com/news/1193890
打開該 URL,發(fā)現(xiàn)確實是對應(yīng)的詳情頁面:

我們觀察該頁面,發(fā)現(xiàn)球迷朋友們的評分都是展示在頁面上的,且是上一期女神的評分,于是我決定把所有的 HTML 下載到本地,然后再慢慢解析頁面,抽取數(shù)據(jù):
def download_page(nvshen_id_list):
    for i in nvshen_id_list:
        print('正在下載ID為' + i + '的HTML網(wǎng)頁')
        url = 'https://www.dongqiudi.com/news/%s' % i
        download = DownloadPage()
        html = download.getHtml(url)
        download.saveHtml(i, html)
        time.sleep(2)

class DownloadPage(object):
    def getHtml(self, url):
        html = requests.get(url=url, cookies=config.session, headers=config.header).content
        return html

    def saveHtml(self, file_name, file_content):
        with open('html_page/' + file_name + '.html''wb'as f:
            f.write(file_content)
download_page 函數(shù)接收一個列表(就是上一個函數(shù)的返回值 nvshen_id_list),通過 requests 庫來請求頁面并保存至本地。同時為了方式請求過于頻繁,做了 2 秒的延時等待設(shè)置。
這里還要注意一點的是,這里是設(shè)置了 cookies 和 headers 的,否則是無法拿到正常 HTML 數(shù)據(jù)的,headers 還是從瀏覽器中手動拷貝出來:
session = {
        'dqduid''yours'}
header = {'User-Agent''Mozilla/5.0 (Windows NT 10.0; Win32; x32; rv:54.0) Gecko/20100101 Firefox/54.0',
        'Connection''keep-alive'}
解析 HTML
對于 HTML 的解析,我依舊使用 BeautifulSoup。主要需要獲取 score 信息,但是由于好多 HTML 頁面寫的都不是很規(guī)則,故而這里耗費了比較多的時間。

對于得分情況,我是這么寫的:
content.find_all('span', attrs={'style''color:#ff0000'})

但是有些頁面的規(guī)則不同,所以會存在無法解析一部分 HTML 文件,對于無法處理的文件,由于也不多,就手工處理了。

當(dāng)然,感覺這里使用正則應(yīng)該會好很多。代碼過長,為了不影響閱讀,就不貼出來了,可以到 GitHub 上查看完整代碼。
def deal_loaclfile(nvshen_id_picture):
    files = os.listdir('html_page/')
    nvshen_list = []
    special_page = []
    for f in files:
        ...
    return nvshen_list, special_page


def get_picture(c, t_list, n_id_p):
    nvshen_l = []
    tmp_prev_id = c.find_all('a', attrs={'target''_self'})
    for j in tmp_prev_id:
        ...
有一部分 HTML 代碼不是很規(guī)范,專門提出了這一部分:
    w_list = ['吳宣儀''30萬''826965''68''825847',
              'https://img1.dongqiudi.com/fastdfs3/M00/74/54/180x135/crop/-/ChOxM1vIPpOAZT8AAAHza_WMyRk175.png']
    g_list = ['關(guān)之琳''20萬''813611''88''812559',
              'https://img1.dongqiudi.com/fastdfs3/M00/6B/94/180x135/crop/-/ChOxM1u1gx2AZ7qmAABi3gRdHS8715.jpg']
    t_list = ['佟麗婭''22萬''797779''93''795697',
              'https://img1.dongqiudi.com/fastdfs3/M00/60/A7/180x135/crop/-/ChOxM1ufUh2AJdR0AABXtcU22fg956.jpg']
    y_list = ['楊丞琳''7萬''1173681''45''1168209',
              'https://img1.qunliao.info/fastdfs4/M00/CA/F7/ChMf8F0pTOKAaefqAA5nOMM0LK0171.jpg']
保存數(shù)據(jù)
對于數(shù)據(jù)的保存,直接保存在了本地的 CSV 中,代碼就不貼了。
完整代碼地址:https://github.com/zhouwei713/data_analysis/tree/master/nvshendahui。
展示網(wǎng)站地址:https://nvshen.luobodazahui.top/。

豆瓣海報爬取

最后,我們再來看看豆瓣的爬取。其實豆瓣網(wǎng)站還是蠻友好的,沒有什么反爬機制,所以我們也需要投桃報李,注意爬蟲的速率,不要訪問過快。
我這里就以女神王祖賢的海報來作為例子。
翻頁分析
在豆瓣電影中搜索“王祖賢”,進入王祖賢主頁后,點擊全部影人圖片,進入到影人圖片頁面。
在該頁面點擊下一頁,可以看到瀏覽器的 URL 變化如下:
https://movie.douban.com/celebrity/1166896/photos/?type=C&start=30&sortby=like&size=a&subtype=a
繼續(xù)使用 Postman 來分析 URL,可以很輕松的得知,start 就是類似于 page 的頁數(shù)控制參數(shù),而且步長為 30,即第一頁是 start = 0,第二頁為 start = 30,第三頁為 start = 60,以此類推。
詳情頁分析
使用 Network 來查看頁面上的圖片信息:
這里我們得到了兩個信息:
  • a 標(biāo)簽中的鏈接可以得到每張圖片的評論信息;

  • img 標(biāo)簽中的鏈接可以用來保存女神的海報。

對于這兩個信息 url,可以分別返回:
def get_posters():
    comment_url_list = []
    picture_list = []
    for i in range(04000030):
        url = 'https://movie.douban.com/celebrity/1166896/photos/?type=C&start=%s&sortby=like&size=a&subtype=a' % str(i)
        req = requests.get(url).text
        content = BeautifulSoup(req, 'html.parser')
        chekc_point = content.find('span', attrs={'class''next'}).find('a')
        if chekc_point != None:
            data = content.find_all('div', attrs={'class''cover'})
            for k in data:
                ulist = k.find('a')['href']
                plist = k.find('img')['src']
                comment_url_list.append(ulist)
                picture_list.append(plist)
        else:
            break
    return comment_url_list, picture_list

之后,就可以下載海報了。

評論獲取
然后我們手動跳轉(zhuǎn)到每周海報的詳情頁面,繼續(xù)查看評論信息。

通過 BeautifulSoup 可以很容易地獲得評論信息,然后保存到 MongoDB 中。
def get_comment(comment_l):
    client = pymongo.MongoClient('mongodb://douban:douban1989@ds149744.mlab.com:49744/douban')
    db = client.douban
    mongo_collection = db.comment
    comment_list = []
    comment = []
    print('Save to MongoDB')
    for i in comment_l:
        response = requests.get(i).text
        content = BeautifulSoup(response, 'html.parser')
        tmp_list = content.find_all('div', attrs={'class''comment-item'})
        comment_list = comment_list + tmp_list
        for k in comment_list:
            tmp_comment = k.find('p').text
            mongo_collection.insert_one({'comment': tmp_comment})
            comment.append(tmp_comment)
    print('Save Finish!')
完整代碼地址:https://github.com/zhouwei713/douban/tree/master/wangzuxian_poster。
爬取的數(shù)據(jù) MongoDB 鏈接:
client = pymongo.MongoClient('mongodb://douban:douban1989@ds149744.mlab.com:49744/douban')
db = client.douban
mongo_collection = db.comment

總結(jié)

本文章分享了五個爬蟲的實戰(zhàn)例子,由于為了照顧篇幅,不至于過長,所以省去了一些繁瑣重復(fù)的代碼解釋。當(dāng)然,代碼部分難免會有些錯誤、不規(guī)范的地方,還請包涵。
在文章中,大部分代碼都是僅僅給出了一些思路和主要框架,還希望勵志于學(xué)習(xí)爬蟲的你,先好好思考爬蟲思路,手動自行敲一遍代碼,這樣才能達(dá)到最好的學(xué)習(xí)效果。
作者:周蘿卜,Python 愛好者,個人公眾號:蘿卜大雜燴。
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
抓取單博主的所有微博及其評論
怎么用Python爬取抖音小視頻? 資深程序員都這樣爬取的(附源碼)
爬Boss直聘,分析2019下半年P(guān)ython工作現(xiàn)狀
當(dāng)科研遇見python
Python圖片爬?。阂绘I下載萬張圖片
[精]兩句話掌握 Python 最難知識點:元類
更多類似文章 >>
生活服務(wù)
熱點新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服