基于搜狗微信的公眾號文章爬蟲

需求分析

先來看一下目標(biāo)網(wǎng)站。


搜狗微信搜索頁面

這次爬取的內(nèi)容是通過搜狗微信的接口獲取微信文章的 url 然后提取目標(biāo)文章的內(nèi)容及公眾號信息。
可以指定內(nèi)容進(jìn)行爬取
那這次需要解決的問題有哪些呢?

需要解決的問題

搜狗微信在沒有登錄的情況下可以爬取十頁信息,我們想要獲取更多的信息只能登錄。在登錄的情況下,爬取數(shù)據(jù)量太大會被封 IP 。這里給出的解決方案是使用代理池的方法。我這里是自己搭建了一個(gè)小的IP代理池,在我以前的文章里有詳細(xì)的描述,可以 點(diǎn)這里 查看。

代碼演示

proxy = None # 聲明代理為 None 也就是開始的時(shí)候用本機(jī)的ip爬取
count_max = 5 # 設(shè)置一個(gè)連接錯(cuò)誤,如果連接超過五次都出錯(cuò)就停止爬取,要不然程序陷入死循環(huán)。
# 請求頭的設(shè)置要加上cookie
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
           }

# 獲取代理
def get_proxy():
    proxy = GetIP()
    return proxy.get_random_ip()

# 請求頁面,這里主要使用了代理,一開始使用的是本機(jī)代理,被封之后換個(gè)ip來爬。
def get_request(url,count=1):
    global proxy
    if count >= count_max:
        print('請求太多次了,這個(gè)方法不行啦,換換吧')
    try:
        if proxy:
            proxies = {'http': 'http://' + proxy}
            r = requests.get(url, headers=headers,proxies=proxies, allow_redirects=False)
        else:
            print('第一次請求,使用本機(jī)的ip')
            r = requests.get(url,headers=headers,allow_redirects=False)
        if r.status_code == 200:
            print('第一頁')
            return r.text
        if r.status_code == 302:
            print('狀態(tài)碼302了,快換代理吧')
            proxy = get_proxy()
            if proxy:
                print('正在使用代理爬取', proxy)
                return get_request(url)
            else:
                print('獲取代理出錯(cuò)')
                return None
    except ConnectionError as e:
        count += 1
        proxy = get_proxy()
        return get_request(url,count)

解釋

這里是整個(gè)代碼的核心,我們先用本機(jī)的 ip 來爬取數(shù)據(jù),如果爬取的量大起來,會封 ip ,然后 url 會重定向到輸入驗(yàn)證碼的頁面,我們可以根據(jù)狀態(tài)碼是 302 來判斷這一情況,然后使用代理。并遞歸調(diào)用函數(shù)本身用ip來爬。
有些時(shí)候狀態(tài)碼不是302,也不是200 ,這時(shí)候就是連接的問題,我們也使用代理來解決這一問題。并計(jì)數(shù),連接出現(xiàn)問題的次數(shù)超過五次就停止,這樣的情況下是別的問題,不要讓在自己調(diào)用自己死循環(huán),退出重新檢查代碼邏輯。
我的代碼里面沒有加 cookie ,使用的時(shí)候加上cookie 才能爬取十頁以后的內(nèi)容。

# 解析頁面得到微信文章的詳情url
def parse_page(html):
    data = etree.HTML(html)
    li = data.xpath('//ul[@class="news-list"]/li')
    for i in li:
        url = i.xpath('./div[2]/h3[1]/a/@href')[0]
        parse_detial(url)
        break

# 解析詳情頁獲取微信公眾號標(biāo)題,作者,內(nèi)容。
def parse_detial(url):
    response = requests.get(url,headers=headers)
    if response.status_code == 200:
        html = etree.HTML(response.text)
        title = html.xpath('//h2[@id="activity-name"]/text()')
        if title:
            title = title[0].strip()
        wechat_name = html.xpath('//a[@id="js_name"]/text()')
        if wechat_name:
            wechat_name = wechat_name[0].strip()
        wechatid = html.xpath('//span[@class="profile_meta_value"]/text()')[0]
        # 獲取內(nèi)容,xpath 雖然好用,但是這一時(shí)半會也沒找到怎么獲取文章內(nèi)容的方法,就用 pyquery 吧,其實(shí)就是css選擇器
        doc = pq(response.text)
        content = doc('.rich_media_content').text()
        result = {'title':title,
                  'wechat_name':wechat_name,
                  'wechatid':wechatid,
                  'content':content}
        print(result)

        #
        # 不適合導(dǎo)出CSV格式,應(yīng)該導(dǎo)出json格式
        # ws = [title,wechat_name,wechatid,content]
        # print(ws)
        # with open('weixin_article.csv','a',newline='') as f:
        #   writer = csv.writer(f)
        #   writer.writerow(ws)

def main():
    # 處理翻頁
    for page in range(1):
        KEYWORD = '數(shù)據(jù)分析' # 這里可以更改關(guān)鍵字
        url = 'https://weixin.sogou.com/weixin?query='+ KEYWORD + '&type=2&page={}'.format(page)
        html = get_request(url)
        parse_page(html)

if __name__ == '__main__':
    main()

這之后的代碼就是常規(guī)的爬蟲寫法,并沒有什么說道。
這里我用 xpath 沒有獲取到文章的內(nèi)容,用了 pyquery 這個(gè)解析庫,其實(shí)就是css 選擇器。應(yīng)該用xpath 也是可以獲取到內(nèi)容的,可能是沒有想到怎么寫,技術(shù)還是要在鍛煉呀。
這里存儲爬取下來的數(shù)據(jù)就沒有再寫下去了,跟之前的一樣就好了,存到mongodb 。我主要是復(fù)習(xí)一下代理 ip 的使用。

本文完!

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

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

  • 這個(gè)項(xiàng)目也是初窺python爬蟲的一個(gè)項(xiàng)目,也是我的畢業(yè)設(shè)計(jì),當(dāng)時(shí)選題的時(shí)候,發(fā)現(xiàn)大多數(shù)人選擇的都是網(wǎng)站類,實(shí)在是...
    夢航韓語閱讀 3,119評論 2 37
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,115評論 25 709
  • 用兩張圖告訴你,為什么你的 App 會卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 14,030評論 2 59
  • 閑來無事或者內(nèi)心煩躁時(shí)練字是最快能令我靜心的方式了。聽著音樂,臨摹上幾帖,最是愜意安寧。還能無形之中提升自己的寫字...
    玥九爺閱讀 1,029評論 0 0
  • 2018年9月8日 閑得無聊寫了一個(gè)用來遍歷所有文件夾的Class,也許以后會用上吧。= =! ListDirUt...
    魚翅大魔王閱讀 325評論 0 0

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