Python 2.7_多进程获取简书专题数据(一)

学python几个月了正好练练手,发现问题不断提高,先从专题入手,爬取些数据,一开始对简书网站结构不熟悉,抓取推荐,热门,城市3个导航栏,交流发现推荐和热门是排序不同,url会重复,以及每个专题详情页三个类目最新评论,最新收录, 热门也会重复 做了下调整,代码执行完毕会返回所有专题的urls元组对象,以便下一步进入每个专题页面解析获取其他数据。注:变量focus关注数,和打开专题后最上面显示的专题关注人数会有差异,例如有的专题关注了10175人,在专题列表页会显示成"10.07k",因此在下一次获取详情页的时候回取到具体数值

多进程获取简书专题数据并写入MySQL数据库

  • 抓取热门和城市页面http://www.jianshu.com/recommendations/collections分类下的所有专题url,专题名字,收录文章数,关注数
  • 定义多个函数获取
    • 获取城市和热门两个分类异步加载的url函数
    • 解析url函数
    • 抓取数据 返回data对象
    • 获取数据存入数据库
    • 多进程   

图1要获取的字段

图2分析异步加载请求构造url

建表

#MySQL数据库建表
CREATE TABLE catetable(
cate_name VARCHAR(255),
cate_url VARCHAR(255),
total_num INT(19),
focus INT(19),
KEY cate_name(cate_name),
KEY cate_url(cate_url)
)ENGINE=INNODB DEFAULT CHARSET=utf8

python代码

#coding:utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
import requests
from lxml import etree
import MySQLdb
from multiprocessing import Pool

'''   
获取所有所有专题所在页的url列表下一步提取每个专题的url
分析:http://www.jianshu.com/recommendations/collections页面为异步加载,查看热门和城市导航栏请求构造url列表
'''
def get_cateurls():
    urls=[]
    for i in range(1, 3):
        cityurl='http://www.jianshu.com/recommendations/collections?page=%s&order_by=city' % i
        urls.append(cityurl)
    for j in range(1,40):
        hoturl='http://www.jianshu.com/recommendations/collections?page=%s&order_by=hot'% j
        urls.append(hoturl)
    return urls

''' 解析页面 ''' 
def get_response(url):
    html=requests.get(url).content
    selector=etree.HTML(html)
    return selector

''' 获取专题数据 得到专题名称 专题url 收录文章数 关注人数 通过zip函数转置数据返回data对象''' 
def get_catedata(url):
    selector=get_response(url)
    cate_url= map(lambda x: 'http://www.jianshu.com'+x, selector.xpath('//div[@id="list-container"]//div[contains(@class,"count")]/a/@href'))
    cate_name=selector.xpath('//div/h4/a/text()')
    total_num=map(lambda x: int(x.strip("篇文章").strip()),selector.xpath('//div[@id="list-container"]//div[contains(@class,"count")]/a/text()'))
    focus1=selector.xpath('//div[@id="list-container"]//div[contains(@class,"count")]/text()')
    focus=[]
    for i in focus1:
        focus_num=i.split("·")[1].rstrip("人关注")
        if "K" in focus_num:
            focus_num=int(float(focus_num[:-1])*1000)
        else:
            focus_num=int(focus_num)
        #print i,focus_num
        focus.append(focus_num)
    data=zip(cate_name,cate_url,total_num,focus)
    return data

''' 写入数据库''' 
def insert_into_Mysql(url):
    try:
        conn=MySQLdb.connect(host='127.0.0.1',user='root',passwd='你的密码',db='local_db',port=3306,charset='utf8')
        with conn:
            cursor = conn.cursor()
            print u'正在加载 %s 页面' % url
            data=get_catedata(url)
            for i in data:
                #print i[0], i[1], i[2],i[3]
                cursor.execute("INSERT INTO  catetable (cate_name,cate_url,total_num,focus) values(%s,%s,%s,%s)", (i[0], i[1], i[2],i[3]))
                conn.commit()
            sql='select * from catetable'
            count = cursor.execute(sql)
            print u'总共输入了%s条数据' % count
    except MySQLdb.Error,e:
        print e


''' 从数据库获取所有的专题url便于以后专题页面数据的进一步获取''' 
def get_allcate_urls_from_mysql():
    try:
        conn = MySQLdb.connect(host='127.0.0.1', user='root', passwd='你的密码', db='local_db', port=3306, charset='utf8')
        with conn:
            cursor = conn.cursor()
            sql = 'select cate_url from catetable'
            count = cursor.execute(sql)
            print u'共输入了%s条数据' % count
            print u'正在获取专题url'
            all_cate_urls=cursor.fetchall()
            return all_cate_urls
    except MySQLdb.Error, e:
        print url,e

''' 多进程执行''' 
def get_allcate_urls():
    urls=get_cateurls()
    pool = Pool(processes=4)
    pool.map(insert_into_Mysql,urls)
    allcate_urls=get_allcate_urls_from_mysql()
    return allcate_urls

''' 先获取到所有专题的数据 下次获取每个专题的数据''' 
if __name__ == '__main__':
    allcate_urls=get_allcate_urls()

  

查看数据表数据

图3数据记录

执行完查询到一共有914个专题,其中城市专题34个,880个热门专题

转载于:https://www.cnblogs.com/Mr-Cxy/p/6391106.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python递归函数是指一个函数在其函数体内调用自己的一种方法。它是一种简洁而有力的编程技巧,适用于解决需要重复进行相同或者相似操作的问题。 在Python中,使用递归函数的语法很简单,只需要在函数体内调用自身并提供适当的终止条件即可。递归函数通常包括两个部分:基本情况和递归情况。 基本情况是指函数可以直接得到结果而不需要调用自身的情况。在遇到基本情况时,递归函数就可以停止递归并返回结果,从而避免无限循环。 递归情况是指函数需要调用自身来解决更小规模的问题的情况。在递归情况下,函数将输入参数缩小到更小的规模,然后再次调用自身,直到达到基本情况。 递归函数可以解决很多问题,比如计算斐波那契数列、计算阶乘、二叉树的遍历等。递归函数的运行过程可以形象地表示为一个函数的调用栈。 需要注意的是,递归函数可能存在性能问题。因为每次递归调用都会创建一个新的函数帧,所以递归函数的内存消耗较大。此外,如果递归调用的深度过大,可能会导致堆栈溢出错误。 为了解决这些问题,可以优化递归函数的实现,比如使用尾递归优化、剪枝等技巧。另外,在使用递归函数时,一定要确定递归结束条件,并尽量避免无限递归的情况。 总之,Python递归函数是一种非常有用的编程技巧,可以简化问题的解决过程。但是在使用时需要注意性能和终止条件,避免出现问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值