【API爬虫】30分钟百万条新浪新闻信息爬取。python得极速之旅

请参考源码,文字是最先得想法,没有再做更改。源码以更新

前期准备:requests库:使用pip install requests 安装。

 pymongo库:使用pip install pymongo安装。

首先分析目标url:http://roll.news.sina.com.cn/news/gnxw/gdxw1/index_1.shtml

这个url的规律很容易发现,我们通过更改index后面的数字便可以实现翻页遍历全部页数。

接着我们审查网页源代码,我们找到html页面中保存连接与新闻标题的部分,还有时间。

发现所有我们需要的信息都保存再li这个标签下面,这里我们可以用正则表达式来获取所有我们需要的信息(标题,连接,日期)

pattern = re.compile(r'<li><.*?href="(.*?)".*?_blank">(.*?)</a><span>(.*?)</span>', re.S)
datas = re.findall(pattern, html)

然后是参与回复与评论的:在获取评论数量时会发现评论是用js的形式发送给浏览器的,所以要先把获取的内容转化为json格式读取python字典

url =http://comment5.news.sina.com.cn/page/info?version=1&format=js&channel=gn&newsid=comos-{需要添加}&group=&compress=0&ie=utf-8&oe=utf-8&page=1&page_size=20

需要添加的部分为标题url的

这样我们可以写出代码:

def get_comm_par(href):
    try:
        id = re.search('doc-i(.+).shtml', href)
        newsid = id.group(1)
        commenturl = 'http://comment5.news.sina.com.cn/page/info?version=1&format=js&channel=gn&newsid=comos-{}&group=&compress=0&ie=utf-8&oe=utf-8&page=1&page_size=20'
        comment = requests.get(commenturl.format(newsid))
        res = json.loads(comment.text.lstrip('var data='))
        return res['result']['count']['total'], res['result']['count']['show']
    except:
        return None
这样我们需要的标题,连接,时间,评论人数,参与人数都得到了。

然后我们把这些信息写入数据库mongodb:

这部分可以写成一个模块在python中引入,还可以加别的参数,实现对网站更深度的遍历。比如root_url。

MONGO_URL = 'localhost'
MONGODB = 'xinlang'
MONGOTABE = 'xinweng'

def write_to_mongodb(res, url):
    if db[MONGOTABE].insert(res):
        print('herf= {} save success'.format(url))
        return True
    print('save fail')
    return False

全部写完后,我们可以为主函数设置多线程,这里用的是python自带的multiprocessing,使用方法也很简单:

pool = multiprocessing.Pool()
pool.map(main, [x for x in range(1, 301)])



最后贴上全部代码

希望对大家有参考作用:

import csv
import threading
import multiprocessing
import json
from urllib.parse import urlencode
from urllib.request import urlopen,Request,urlparse,build_opener,install_opener
from  urllib.error import URLError,HTTPError






def html_download(url):
    headers = {'User-Agent': "User-Agent:Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)"}
    request = Request(url, headers=headers)
    try:
        html = urlopen(request).read().decode()
    except HTTPError as e:
        html = None
        print('[W] 下载出现服务器错误: %s' % e.reason)
        return None
    except URLError as e:
        html = None
        print("[E] 站点不可达: %s" % e.reason)
        return None
    return html


def api_info_manager(page):
    #http://api.roll.news.sina.com.cn/zt_list?channel=news&cat_1=gnxw&show_all=1&show_num=6000&tag=1&format=json
    comment_channel = [ 'gnxw', 'shxw','gjxw']
    for comment in comment_channel:


        data= {
            'channel':'news',
            'cat_1':comment,
            'show_all':1,
            'show_num':6000,
            'tag':1,
            'page':page,
            'format':'json'
            }
        dataformat = 'http://api.roll.news.sina.com.cn/zt_list?'+urlencode(data)
        response = html_download(dataformat)
        #print(response)
        json_results  = json.loads(response,encoding='utf-8')['result']['data']
        for info_dict in json_results:
            yield info_dict


fileheader = ['id','column','title','url','keywords','comment_channel','img','level','createtime','old_level','media_type','media_name']


def write_csv_header(fileheader):  
    with open("新浪新闻.csv", "a",newline='') as csvfile:  
        writer = csv.DictWriter(csvfile, fileheader)  
        writer.writeheader()  


def save_to_csv(result):
    with open("新浪新闻.csv", "a",newline='') as csvfile:  
            print('    正在写入csv文件中.....')  
            writer = csv.DictWriter(csvfile, fieldnames=fileheader)  
            writer.writerow(result) 


def main(page):
    for res in api_info_manager(page):
        save_to_csv(res)


if __name__ == '__main__':
        #多线程  
    write_csv_header(fileheader)   
    pool = multiprocessing.Pool()  
    # 多进程  
    thread = threading.Thread(target=pool.map,args = (main,[x for x in range(1, 100)]))  
    thread.start()  
    thread.join()

喜欢爬虫的可以加我Q(四七零五八一九八五)交流,我后面会更新自己在机器学习和大数据方面的探索。因为还在实习,而且python学习时间不长,如有纰漏,希望大家点评。


猜你喜欢

转载自blog.csdn.net/qq_41664845/article/details/79135082