python实现用线程爬虫 快速高效爬数据

前言

线程可以高效的调用cpu,实现cpu利用的最大化,非常快速的帮助我们爬取想要的数据

一、线程的特点

线程的含义:线程相当于 一个公司的员工,也相当于 一个应用软件可以使用多个功能一样
线程的方法:Class MyThread(Thread):继承Thread父类
new Mythread()创建对象 t.start()开启线程 Thread父类的方法def run(self):
是线程要完成的任务

二、使用步骤

1.线程池

ThreadPoolexecutor(count)这个就是线程池对象 count代表在线程内的数量
我们爬取数据都是用线程池 ,线程池相当于多个线程构成一块

 with ThreadPoolExecutor(50) as t:
        for i in range(1,200):
            data = {'limit': '20',
                    'current': str(i),
                    'pubDateStartTime': '',
                    'pubDateEndTime': '',
                    'prodPcatid': '',
                    'prodCatid': '',
                    'prodName': ''}
            t.submit(download_one_page(data))#submit第一个是参数 正是线程池要干的事
            # t.submit(download_one_page,第二个参数) 第二个参数是指 传入 download_one_page中

2.引入库

代码如下(示例):

import requests
from lxml import etree
from concurrent.futures import ThreadPoolExecutor
import csv

3.整块代码

import requests
from lxml import etree
from concurrent.futures import ThreadPoolExecutor
import csv
headers = {"User-Agent":"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:48.0) Gecko/20100101 Firefox/48.0"}
data = {'limit':'20',
'current':'1',
'pubDateStartTime':'',
'pubDateEndTime':'',
'prodPcatid':'',
'prodCatid':'',
'prodName':''}
datalists = []
f = open("./北京菜价数据1.csv",mode="w",encoding="utf-8")
f = csv.writer(f)
def download_one_page(data):
    url = "http://www.xinfadi.com.cn/getPriceData.html"
    resp = requests.post(url=url,headers=headers,data=data) #可以用post方式提交表单 访问的到
    list = resp.json()
    list = list['list']# 获取数据列表
    print(len(list))  # 打印数据长度
    for i in range(len(list)):
        datalist = []
        id = list[i]['id']  # 菜的id
        name = list[i]['prodName']  # 菜名
        typeone = list[i]['prodCat']  # 一级分类
        place = list[i]['place']  # 位置
        lowPrice = list[i]['lowPrice']  # 最低价
        highPrice = list[i]['highPrice']  # 最高价
        avgPrice = list[i]['avgPrice']  # 平均价格
        datalist.append(id)
        datalist.append(name)
        datalist.append(typeone)
        datalist.append(place)
        datalist.append(lowPrice)
        datalist.append(highPrice)
        datalist.append(avgPrice)
        f.writerow(datalist)
    #     datalists.append(datalist)
    # return datalists
def main():
    pass
if __name__ == '__main__':
    #低效率事件
    """for i in range(1,14870):
        data = {'limit': '20',
                'current': str(i),
                'pubDateStartTime': '',
                'pubDateEndTime': '',
                'prodPcatid': '',
                'prodCatid': '',
                'prodName': ''}
        datalists = download_one_page(data)"""
    with ThreadPoolExecutor(50) as t:
        for i in range(1,200):
            data = {'limit': '20',
                    'current': str(i),
                    'pubDateStartTime': '',
                    'pubDateEndTime': '',
                    'prodPcatid': '',
                    'prodCatid': '',
                    'prodName': ''}
            t.submit(download_one_page(data))#submit第一个是参数 正是线程池要干的事
            # t.submit(download_one_page,第二个参数) 第二个参数是指 传入 download_one_page中
            f.close()
    print("执行完毕!")

总结

线程池的方法比较重要 submit(要执行的任务)

上一篇:React map生成元素添加点击事件绑定this


下一篇:使用原生js + css 实现一个文字轮播效果(一)