美文网首页
爬取搜狗微信文章和公众号文章

爬取搜狗微信文章和公众号文章

作者: 小温侯 | 来源:发表于2018-07-21 00:21 被阅读460次

    思路

    本来想着爬一下微信文章,后来发现搜狗的微信搜索是静态页面,顿时索然无味。

    不过只要想做,就总能找到没学过的东西。比如说,将文章内容用Markdown保存下来。另外,我发现现在搜狗搜索里公众号文章只能显示前10篇了,似乎用搜狗爬取微信文章的路被断了。我粗略看了一下,用微信客户端还是可以访问的,但网页版不行,PC端的可以,手机端应该也可以。登陆其实还好解决,其余只能看抓包了,之后有机会做一下。

    听说微信和知乎都在封IP,所以下一步我准备先把代理池做起来。

    言归正传,怎么爬取文章的思路我就不说了,这里主要说下如何把文章内容转化为markdown格式并保存到本地。

    HTML转Markdown

    我在网上找到了两个html转md库:tombhtml2text。两个我都试了,后来选了前面那个,是位成都朋友写的。不过不管是哪个,转换之后都有一些不尽如意,比如说:图片视频没处理;有残留的<br><strong>标签等等。

    我这里是在使用tomb库之前先用BeautifulSoup将内容做了预处理,具体的处理如下:

    • 提取文章标题,规整作者,公众号名字和文章发布时间字段。

    • 关于<img>标签,将图片的名字(如果有的话,没有自己取一个)和地址提取出来,替换成类似于<span>![图片名字](图片地址)</span>的结构,同时把图片保存到当前位置的_images目录下。

    • 关于iframe,多用于视频的标签,替换成类似于<span>[视频名](视频地址)</span>的结构,后续会被转为超链接。

    • 去除所有的<br/>, <br></br>标签。

    • 去除文章末尾赞赏部分的内容。

    这里为什么图片和视频要被替换为span标签,是因为BeautifulSoup库不能直接添加字符串(会被转为&alt, &amp之类的符号),好在bs也提供了一些修改HTML结构的方法,比如说insert_after()decompose(),具体的可以看官方文档

    后续的话,我打算写一个HTML转MD的库,名字就叫ohhtml2md

    代码

    效果

    下载之后如图:

    wechat-download.jpg

    如果用类似Typora可以直接解析md的编辑器,可以直接进行阅读:

    wechat-article.gif

    但是有些内容的换行其实是有问题的。

    wechat.py

    import requests
    import time
    from bs4 import BeautifulSoup
    from random import choice
    import tomd
    import os
    import Configure
    
    header = {}
    header['user-agent'] =  choice(Configure.FakeUserAgents)
    
    def getOnePageURLs():
        payload = {
            'type':2,
            's_from':'input',
            'query':'garmin fenix 5',
            'ie':'utf8'
        }
    
        url = "http://weixin.sogou.com/weixin"
        try:
            response = requests.get(url, headers=header, params=payload)
            content = None
    
            if response.status_code == requests.codes.ok:
                content = response.text
                
        except Exception as e:
            print (e)
    
        soup = BeautifulSoup(content, 'lxml')
    
        news_list = soup.find(class_='news-list').find_all('li')
    
        for new in news_list:
            getContent(new.a.get('href').strip())
            #break
    
    def getContent(url):
        try:
            response = requests.get(url, headers=header)
            content = None
    
            if response.status_code == requests.codes.ok:
                content = response.text
                
        except Exception as e:
            print (e)
        
        soup = BeautifulSoup(content, 'lxml')   
    
        if not os.path.isdir("Download"):
            os.mkdir("Download")
    
        html_content_parser(soup)
        
    def html_content_parser(soup):
        html_content = soup.find(id='img-content')
    
        # 获取标题,构建文件名
        title = html_content.find(class_='rich_media_title')
        title.string = title.text.strip()
    
        filename = title.text.strip().replace('|','-') + '.md'
        
        # 筛选作者信息
        profile_name = html_content.find(class_='rich_media_meta').a.text.strip()
        publish_time = html_content.find(id='meta_content').em.text.strip()
    
        author = html_content.find(id='meta_content').find('p',class_='rich_media_meta_primary')
        author = author.text.strip()[3:] if author else None
    
        new_tag = soup.new_tag('p')
        new_tag.string = "公众号: " + profile_name
        title.insert_after(new_tag)
    
        new_tag2 = soup.new_tag('p')
        new_tag2.string = "发布时间: " + publish_time
        new_tag.insert_after(new_tag2)
    
        if author:
            new_tag3 = soup.new_tag('p')
            new_tag3.string = "作者: " + author
            new_tag2.insert_after(new_tag3)
    
        html_content.find(id='meta_content').decompose()
        
        # 去除赞赏
        html_content.find(class_='reward_area').decompose()
        html_content.find(class_='reward_qrcode_area').decompose()
    
        # 处理图片
        ## 文件夹
        dir_name = "Download/_images"
        if not os.path.isdir(dir_name):
            os.mkdir(dir_name)
        
        ## 下载并替换为本地图片
        cnt = 1
        
        images = html_content.find_all('img')
    
        if images:
            for image in images:
                img_src = image.get('data-src')
                img_type = image.get('data-type')
                img_name = "{0:s}_{1:d}.{2:s}".format(filename[:-3], cnt, img_type if img_type else 'png')
                cnt += 1
    
                file_path = "Download/_images/{0:s}".format(img_name)
                with open (file_path, 'wb') as file:
                    response = requests.get(url = img_src)
                    for block in response.iter_content(1024):
                        if block:
                            file.write(block)
                        else:
                            break
                
                tag = soup.new_tag('span')
                tag.string = "![](_images/{0:s})".format(img_name)
                image.replace_with(tag)
    
        # 处理视频
        videos = html_content.find_all('iframe')
        if videos:
            for video in videos:
                video_src = video.get('data-src')
    
                tag = soup.new_tag('span')
                tag.string = "[此处是视频]({0:s})".format(video_src)
                video.replace_with(tag)
        
    
        # 去除<br/> <br></br>
        brs = html_content.find_all('br')
        if brs:
            for br in brs:
                br.decompose()
    
        mdText = str(html_content).replace('<br/>','')
    
        mdText = tomd.Tomd(mdText).markdown
    
        with open("Download/"+filename, 'w', encoding='utf8') as file:
            file.write(mdText)
    
    
    if __name__ == '__main__':
        getOnePageURLs()
    

    相关文章

      网友评论

          本文标题:爬取搜狗微信文章和公众号文章

          本文链接:https://www.haomeiwen.com/subject/gwycmftx.html