4.6 爬虫效率化

本节在4.5节的基础上,将爬虫优化成多进程爬虫,以提高爬虫效率。通过之前的爬虫了解到该网站中的出发地共有700多个,可以根据出发地同时调用多个CPU,每个CPU运行一个出发地的脚本。笔者的电脑逻辑CPU个数是8,因此每次可以同时获取8个出发地的数据。

.py文件内容、自定义函数,以及将文件命名为qunar的相关代码如下。

import requests
import urllib
import time
import pymongo

client = pymongo.MongoClient('localhost',27017)
book_qunar = client['qunar']
sheet_qunar_111 = book_qunar['qunar_111']
headers = {
    "cookie": "QN1=00001d80075816179a202bf8; QN300=organic; QN48=tc_f16fbad98113c317_16b788ad2eb_c6fe; _RF1=36.110.118.134; _RSG=s2q26YN7uhCLRxFTBFcimB; _RDG=28a5b8a8ad72ce2"
}
def get_list(dep,item):
    url = 'https://touch.dujia.qunar.com/list?modules=list%2CbookingInfo%2CactivityDetail&dep={}&query={}&dappDealTrace=true&mobFunction=%E6%89%A9%E5%B1%95%E8%87%AA%E7%94%B1%E8%A1%8C&cfrom=zyx&it=dujia_hy_destination&date=&needNoResult=true&originalquery=%E4%B8%BD%E6%B1%9F%E8%87%AA%E7%94%B1%E8%A1%8C&limit=0,20&includeAD=true&qsact=search'.format(
        urllib.request.quote(dep), urllib.request.quote(item), urllib.request.quote(item)
    )
    strhtml = get_json(url)
    routeCount = int(strhtml['data']['limit']['routeCount'])
    for limit in range(0, routeCount, 20):
        url = 'https://touch.dujia.qunar.com/list?modules=list%2CbookingInfo%2CactivityDetail&dep={}&query={}&dappDealTrace=true&mobFunction=%E6%89%A9%E5%B1%95%E8%87%AA%E7%94%B1%E8%A1%8C&cfrom=zyx&it=dujia_hy_destination&date=&needNoResult=true&originalquery=%E4%B8%BD%E6%B1%9F%E8%87%AA%E7%94%B1%E8%A1%8C&limit=0,20&includeAD=true&qsact=search'.format(
            urllib.request.quote(dep), urllib.request.quote(item),
            urllib.request.quote(item), limit)
        strhtml = get_json(url)
        result = {
            'date': time.strftime('%Y-%m-%d', time.localtime(time.time())),
            'dep': dep,
            'arrive': item,
            'limit': limit,
            'result': strhtml
        }
        sheet_qunar_111.insert_one(result)

def connect_mongo():
    client = pymongo.MongoClient('localhost', 27017)
    book_qunar = client['qunar']
    sheet_qunar_111 = book_qunar['qunar_111']

def get_json(url):
    strhtml = requests.get(url, headers=headers)
    time.sleep(1)
    return strhtml.json()

def get_all_data(dep):
    a = []
    url = 'https://touch.dujia.qunar.com/golfz/sight/arriveRecommend?dep={}&exclude=&extensionImg=255,175'.format(
        urllib.request.quote(dep))
    arrive_dict = get_json(url)
    for arr_item in arrive_dict['data']:
        for arr_item_1 in arr_item['subModules']:
            for query in arr_item_1['items']:
                if query['query'] not in a:  # 新增去重代码
                    a.append(query['query'])  # 新增去重代码
    for item in a:
        get_list(dep, item)

dep_list = '''
    马鞍山
    茂名
    眉山
    梅州
    惠州
    葫芦岛
    呼伦贝尔
    湖州

'''



if __name__ == "__main__":
    url = 'https://touch.dujia.qunar.com/depCities.qunar'
    # headers = {
    #     "cookie": "QN1=00001d80075816179a202bf8; QN300=organic; QN48=tc_f16fbad98113c317_16b788ad2eb_c6fe; _RF1=36.110.118.134; _RSG=s2q26YN7uhCLRxFTBFcimB; _RDG=28a5b8a8ad72ce2"
    # }
    dep_dict = get_json(url)
    for dep_item in dep_dict['data']:
        for dep in dep_dict['data'][dep_item]:
            a = []  # 新增去重代码
            url = 'https://touch.dujia.qunar.com/golfz/sight/arriveRecommend?dep={}&exclude=&extensionImg=255,175'.format(
                urllib.request.quote(dep))
            arrive_dict = get_json(url)
            for arr_item in arrive_dict['data']:
                for arr_item_1 in arr_item['subModules']:
                    for query in arr_item_1['items']:
                        if query['query'] not in a:  # 新增去重代码
                            a.append(query['query'])  # 新增去重代码
            for item in a:
                get_list(dep,item)

接下来新建一个新的Python File,命名为main.py,代码如下。

from qunar import get_all_data  #从qunar文件中导入get_all_data函数
from qunar import dep_list  #从qunar文件中导入dep_list函数
from multiprocessing import Pool  #从multiprocessing库中导入Pool函数

if __name__ == "__main__":
    pool = Pool()
    pool.map(get_all_data,dep_list.split())

多进程爬虫用的库是Pool(注意输入Pool时,第一个字母必须是大写),Pool()函数可以自定义多进程的数量,不设置时代表默认有多少个CPU就开多少个进程。

最后使用pool.map将第二个参数映射到第一个参数(函数)上。

 

posted @ 2019-06-25 14:37  taoziya  阅读(201)  评论(0)    收藏  举报