python爬蟲日誌(10)多進程爬取豆瓣top250

又是一個實踐,此次準備爬取豆瓣電影top250,並把數據保存到mysql中,雖然說數據量不大,對速度沒有太大的要求,不過爲了練習多進程爬蟲,仍是用多進程的方法寫了這個爬蟲。python

多進程有什麼用呢?在數據量少的時候,用不用多進程問題不大,但當數據量大的時候,多進程在效率提高上的做用就很是突出了。進程每多一個,速度就提高一倍,好比個人電腦是4核的,默認開4個進程(固然能夠本身設置,但不宜過多),那麼效率就能提高四倍。下面來看代碼吧。mysql

from bs4 import BeautifulSoup
import requests, get_proxy, pymysql
from multiprocessing import Pool  #多進程須要用到的庫,pool能夠稱爲進程池


douban_urls = ['https://movie.douban.com/top250?start={}&filter='.format(i) for i in range(0, 250, 25)]
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"}
proxy_list = get_proxy.get_ip_list()   #爬取代理的函數能夠看個人上一篇日誌
db = pymysql.connect('localhost', 'root', '', 'doubantop250')  #連接數據庫
cursor = db.cursor()


def get_info(douban_url):
    proxies = get_proxy.get_random_ip(proxy_list)   #設置代理,返回一個字典
    wb_data = requests.get(douban_url, headers=headers, proxies=proxies)
    soup = BeautifulSoup(wb_data.text, 'lxml')
    item_list = soup.find_all('div', 'item')
    for item in item_list:
        link = item.select('div.hd > a')[0].get('href')
        title = item.select('div.hd > a > span:nth-of-type(1)')[0].text
        info = item.select('.info .bd p:nth-of-type(1)')[0].text.split('/')
        year = info[-3].split()[-1]
        country = info[-2].strip()
        types = info[-1].strip()
        star = item.select('.rating_num')[0].text
        db.ping(reconnect=True)  #不知道爲何使用多進程,總會發生InterfaceError (0, '')這個錯誤,因此每次執行語句以前先確保鏈接正常,就是Ping一下
        sql = '''INSERT INTO top250(link,title,year,country,type,star) VALUES("{}","{}",{},"{}","{}",{})'''.format(link, title, year, country, types, star)
        try:
            cursor.execute(sql)
            db.commit()   #這個函數用於同步數據庫數據,若是不想由於可能引起一個錯誤,停止程序運行,使得前面抓的數據沒有記錄到數據庫中就每次作修改後調用一下
        except pymysql.err.ProgrammingError:
            print(sql, '\n', douban_url)  #這裏有一條數據比較特殊,因此會引起語法錯誤,不要緊先跳過


if __name__ == '__main__':  #這條語句是必須的,至於爲何,能夠不寫這行,直接運行下面兩行看看,ide會有提示說必須在這下面運行,因此要加上。其實這個__name__ == '__main__'就是證實程序是獨自運行,而不是被其餘程序調用而運行的,意思就像是我就是我本身。多進程就得在這種狀態下才能夠進行。
    pool = Pool() #能夠用Pool(processes=)來設置進程數
    pool.map(get_info, douban_urls)  #map這個函數,能夠將後面的列表裏的元素,一個個做爲參數放到前面的函數中運行,有個約定函數在map中做爲參數能夠不寫括號
db.close()

成果sql

固然由於有一條數據比較特殊因此少了一條。少的那條是數據庫

能夠看到這裏有多個時間,而且後面有括號裏的多餘的內容,不過不要緊,由於只有一條比較特殊,單獨處理下就行了。dom

相關文章
相關標籤/搜索