Python 2.7_多進程獲取簡書專題數據(一)

學python幾個月了正好練練手,發現問題不斷提升,先從專題入手,爬取些數據,一開始對簡書網站結構不熟悉,抓取推薦,熱門,城市3個導航欄,交流發現推薦和熱門是排序不一樣,url會重複,以及每一個專題詳情頁三個類目最新評論,最新收錄, 熱門也會重複 作了下調整,代碼執行完畢會返回全部專題的urls元組對象,以便下一步進入每一個專題頁面解析獲取其餘數據。注:變量focus關注數,和打開專題後最上面顯示的專題關注人數會有差別,例若有的專題關注了10175人,在專題列表頁會顯示成"10.07k",所以在下一次獲取詳情頁的時候回取到具體數值html

多進程獲取簡書專題數據並寫入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個熱門專題python

相關文章
相關標籤/搜索