5. 抓取微信号的文章

平时在看公众号的时候,一直在想怎么才能抓取里面的文章。
知道网址就很容易抓取了,而每篇文章右上角都有一个用Safari打开的入口。把网址拷下来,抓取还不是易如反掌吗。

这里写图片描述

不过既然要用爬虫来抓取,那还是要批量显得更有效率一点。

那么现在,在搜狗和微信公众号的合作下,我们可以在PC端直接浏览公众号文章,及其列表!!

这里写图片描述

燃鹅,我这次的目标是平时挺喜欢看的DeepTech深科技。
为了更方便,我就直接锁定这个公众号的微信号。这是唯一的。

这里写图片描述

此时网址为 :

sug=y&sug_type=&w=01019900&sut=13810238&sst0=1505198125147&lkt=0%2C0%2C0”>http://weixin.sogou.com/weixin?type=1&s_from=input&query=mit-tr&ie=utf8&sug=y&sug_type=&w=01019900&sut=13810238&sst0=1505198125147&lkt=0%2C0%2C0

经观察可以看见,query这个参数的值就是我要搜索的mit-tr
接下来就是用网址的开发者工具得出获得这个公众号的入口网址
这个过程就省略。。。。。
直接上代码

def getWeixinhao(sgUrl):
    head = {'User-Agent' : r'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.3103.400'}
    request1 = request.Request(sgUrl, headers = head)
    response = request.urlopen(request1)
    sgSoup = BeautifulSoup(response, 'lxml')
    eachLi = sgSoup.find_all('li')
    for li in eachLi:
        if(li.find(class_ = 'tit') != None):
                getData(li.find(class_ = 'tit').a.get('href'))


if __name__ == '__main__':
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8')
    # 设置递归深度
    sys.setrecursionlimit(1000000)
    weixinHao = 'mit-tr'
    '''
      因为网址这里,如果有多个%,后面那个%(weixinHao)就会不知道  
      匹配哪个, 所以是%的就用%%来表示。
    '''
    getWeixinhao('http://weixin.sogou.com/weixin?type=1&s_from=input&query=%s&ie=utf8&_sug_=y&_sug_type_=&w=01019900&sut=3706&sst0=1505180448968&lkt=5%%2C1505180447462%%2C1505180448866' %(weixinHao))

记得把自己伪装成不是爬虫啊, 现在很多网站都不喜欢机器人浏览它的页面呢。

然后接下来我们就要获取其文章列表了,其实套路都一摸一样吧。
不过我想试试 selenium + PhantomJS 的效果,这个组合的用处主要用于抓取动态页面—js。

def getData(url):
    headUrl = 'https://mp.weixin.qq.com'
    browser = webdriver.PhantomJS()
    browser.get(url)

    soup = BeautifulSoup(browser.page_source, 'lxml')
    urlSet = soup.find_all('h4')
    # 获取每篇文章 url
    for url in urlSet:
        getContent('%s%s' %(headUrl, url.get('hrefs')))
        # 设置时间间隔,减轻服务器负担并让别人认为你更像个人类
        time.sleep(5)

    browser.quit()

获取内容后我就可以获得它的内容了, 因为图片的下载速度和文章的下载速度差得有点远,所以我选择采用两个进程来分别处理图片和文章并存放到不同的文件夹中。
爬取内容中,最耗时间的其实就是如何获得想要内容的TAG并得到它的内容。

def getContent(url):
    head = {'User-Agent' : r'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.3103.400'}
    request1 = request.Request(url, headers = head)
    response = request.urlopen(request1)
    soup = BeautifulSoup(response, 'lxml')
    title = soup.find(class_ = 'rich_media_title')
    content = soup.find(class_ = 'rich_media_content ')

    pA = Process(target = getImage, args = (content, title,))
    pI = Process(target = getArticle, args = (content, title))

    pA.start()
    pI.start()

    pA.join()
    pI.join()
    print('抓取完成 : %s' %(str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))))

def getArticle(content, title):
    print('开始抓取文本 : %s' %(str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))))

    eachP = content.find_all('p')
    with open(file = 'ArticleFloder/%s.txt' %(title.get_text().split()[0]), mode = 'a', encoding = 'utf-8') as article:
        for p in eachP:
            text = p.find_all('span')
            if len(text) > 0:
                for s in text:
                    if 'ArticleFloder' not in os.listdir():
                        os.makedirs('ArticleFloder')
                    article.write(s.get_text())
            article.write('\n')
    print('完成文本下载 : %s' %(str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))))


def getImage(content, title):
    print('开始抓取图片 : %s' %(str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))))

    i = 0
    imgSet = content.find_all('img')
    if 'imgFloder' not in os.listdir():
        os.makedirs('imgFloder')
    for img in imgSet:
        if 'gif' not in img.get('data-src'):
            urlretrieve(url = img.get('data-src') , filename = 'imgFloder/%s%s.jpg' %(title.get_text().split()[0], i))
        else:
            urlretrieve(url = img.get('data-src') , filename = 'imgFloder/%s%s.gif' %(title.get_text().split()[0], i))
        i+= 1
    print('完成图片下载 : %s' %(str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))))

在控制台中就是这个效果。

这里写图片描述

文件夹
这里写图片描述

这里写图片描述

这里写图片描述

不过我代码里面并没有区分内容的附图和广告的附图,所以可以看到很多重复的图片,同时也影响了下载的速度。这是不足之处之一。

最后还是附上一个全代码吧:

# -*- coding:utf-8 -*-
import urllib.request as request
from urllib.request import urlretrieve
from bs4 import BeautifulSoup
from multiprocessing import Process
from selenium import webdriver
import time, datetime
import sys, io, os


def getData(url):
    headUrl = 'https://mp.weixin.qq.com'
    browser = webdriver.PhantomJS()
    browser.get(url)
    # result = reponse.find_element_by_class_name('weui_media_title')
    soup = BeautifulSoup(browser.page_source, 'lxml')
    urlSet = soup.find_all('h4')
    for url in urlSet:
        getContent('%s%s' %(headUrl, url.get('hrefs')))
        time.sleep(5)
        # break
    browser.quit()

def getContent(url):
    head = {'User-Agent' : r'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.3103.400'}
    request1 = request.Request(url, headers = head)
    response = request.urlopen(request1)
    soup = BeautifulSoup(response, 'lxml')
    title = soup.find(class_ = 'rich_media_title')
    content = soup.find(class_ = 'rich_media_content ')

    pA = Process(target = getImage, args = (content, title,))
    pI = Process(target = getArticle, args = (content, title))

    pA.start()
    pI.start()

    pA.join()
    pI.join()
    print('抓取完成 : %s' %(str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))))

def getArticle(content, title):
    print('开始抓取文本 : %s' %(str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))))

    eachP = content.find_all('p')
    with open(file = 'ArticleFloder/%s.txt' %(title.get_text().split()[0]), mode = 'a', encoding = 'utf-8') as article:
        for p in eachP:
            text = p.find_all('span')
            if len(text) > 0:
                for s in text:
                    if 'ArticleFloder' not in os.listdir():
                        os.makedirs('ArticleFloder')
                    article.write(s.get_text())
            article.write('\n')
    print('完成文本下载 : %s' %(str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))))


def getImage(content, title):
    print('开始抓取图片 : %s' %(str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))))

    i = 0
    imgSet = content.find_all('img')
    if 'imgFloder' not in os.listdir():
        os.makedirs('imgFloder')
    for img in imgSet:
        if 'gif' not in img.get('data-src'):
            urlretrieve(url = img.get('data-src') , filename = 'imgFloder/%s%s.jpg' %(title.get_text().split()[0], i))
        else:
            urlretrieve(url = img.get('data-src') , filename = 'imgFloder/%s%s.gif' %(title.get_text().split()[0], i))
        i+= 1
    print('完成图片下载 : %s' %(str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))))


def getWeixinhao(sgUrl):
    head = {'User-Agent' : r'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.3103.400'}
    request1 = request.Request(sgUrl, headers = head)
    response = request.urlopen(request1)
    sgSoup = BeautifulSoup(response, 'lxml')
    eachLi = sgSoup.find_all('li')
    for li in eachLi:
        if(li.find(class_ = 'tit') != None):
                getData(li.find(class_ = 'tit').a.get('href'))


if __name__ == '__main__':
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8')
    sys.setrecursionlimit(1000000)
    weixinHao = 'mit-tr'
    getWeixinhao('http://weixin.sogou.com/weixin?type=1&s_from=input&query=%s&ie=utf8&_sug_=y&_sug_type_=&w=01019900&sut=3706&sst0=1505180448968&lkt=5%%2C1505180447462%%2C1505180448866' %(weixinHao))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值