day 7-多线程技术学习总结

day 7-多线程技术

1.字体反爬

import requests
headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36'
}


code = {
    '0xE1D0': '8',
    '0xE325': '2',
    '0xE41D': '3',
    '0xe52e': '4',
    '0xe630': '5',
    '0xe76e': '7',
    '0xe891': '1',
    '0xe9ce': '0',
    '0xeaf2': '9',
    '0xec4c': '6'
}

new_code = dict((f'&#{eval(x)}', code[x]) for x in code)

# print(new_code)


url = 'https://mapi.guazi.com/car-source/carList/pcList?osv=IOS&minor=&sourceType=&ec_buy_car_list_ab=&location_city=&district_id=&tag=-1&license_date=&auto_type=&driving_type=&gearbox=&road_haul=&air_displacement=&emission=&car_color=&guobie=&bright_spot_config=&seat=&fuel_type=&order=&priceRange=0,-1&tag_types=&diff_city=&intention_options=&initialPriceRange=&monthlyPriceRange=&transfer_num=&car_year=&carid_qigangshu=&carid_jinqixingshi=&cheliangjibie=&page=1&pageSize=20&city_filter=12&city=12&guazi_city=12&qpres=&platfromSource=wap&versionId=0.0.0.0&sourceFrom=wap&deviceId=d9217098-1286-47a7-af41-d0e4644a52f8'
response = requests.get(url, headers=headers)
result = response.json()

for x in result['data']['postList']:
    first_pay = x['first_pay'].split(';')
    new_first_pay = []
    for i in first_pay:
        if i in new_code:
            new_first_pay.append(new_code[i])
        elif i[1:] in new_code:
            new_first_pay.append('.' + new_code[i[1:]])
        else:
            new_first_pay.append(i)
    first_pay = ''.join(new_first_pay)
    print(first_pay)

2.认识多线程和多进程

1.什么是进程

一个正在运行的应用程序就是一个进程

进程是系统分配内容的最小单位。

每个进程均运行在其专门且受保护的内存空间中,当进程结束的时候,这个进程对应的内存空间会自动释放。

2.线程

线程是进程执行任务的基本单元。

进程中的任务都在线程中执行的(如果一个进程中没有线程,那么这个进程对应的程序什么事情都做不了)。

进程 - 车间(工厂), 提供厂房以及厂房中保存资源

线程 - 车间工人

默认情况下,一个进程中有一个线程。

3.多线程

一个进程中有多个线程

单线程特点:一个线程执行多个任务,只能串行(一个一个按顺序)执行。

多线程特点:多个线程执行多个任务,可以并行(同时)执行。

单线程 - 一个工厂中只有一个工人

多线程 - 一个工厂中同时有多个工人,多线程的存在可以提高程序的效率。

手机应用程序:3 ~ 5线程

电脑应用程序:200 ~ 300个

4.多线程的原理

一个cpu同一时间只能处理一个线程,同一时间只有一个线程可以工作。

多线程的原理: 多线程技术其实就是利用CPU空闲时间做其他事情。

3.使用多线程

import time
from datetime import datetime
from threading import Thread, current_thread

1.主线程和子线程

一个进程默认只有一个线程,这个线程就是主线程,除了主线程以外的线程都是子线程。

子线程需要由程序员自己创建

什么时候需要子线程,什么时候就创建线程对象: Thread - 线程类

def download(name):
    print(f'======{name}开始下载:{datetime.now()}======')
    print(current_thread())
    time.sleep(2)
    print(f'======{name}下载结束:{datetime.now()}======')


if __name__ == '__main__':
    # 方案1:在主线程中直接下载三个电影
    # download('肖申克的救赎')
    # download('霸王别姬')
    # download('阿甘正传')

    # 方案2:在三个子线程中分别下载三个电影
    # 1)创建线程对象: Thread(*,target=函数, args=元组)
    # target: 需要在子线程中执行的任务(以函数的形式提供)
    # args: 元组中的元素就是在调用target对应的函数的时候的实参
    t1 = Thread(target=download, args=('肖申克的救赎',))
    t2 = Thread(target=download, args=('霸王别姬',))
    t3 = Thread(target=download, args=('阿甘正传',))

    # 2)启动线程  - 在子线程中调用target对应的函数,参数就传args中的数据
    # 线程对象.start()
    t1.start()
    t2.start()
    t3.start()

4.多线程获取豆瓣电影数据

import requests
from lxml import etree
from re import sub
import csv
from threading import Thread
def get_page_data(page):
    print(f'第{page//25}页数据开始下载')
    # 1.获取网页数据
    url = f'https://movie.douban.com/top250?start={page}&filter='
    headers = {
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36',
        'cookie': 'bid=2L4tF88mhxQ; ll="118318"; dbcl2="222590700:FVo7RHfVAd4"; ck=P4n_; push_noty_num=0; push_doumail_num=0'
    }
    response = requests.get(url, headers=headers)

    # 2. 使用xpath解析数据
    root = etree.HTML(response.text)
    all_div = root.xpath('//ol[@class="grid_view"]/li/div')
    all_data = []
    for div in all_div:
        # 电影名字
        name = div.xpath('./div/div[@class="hd"]/a/span[1]/text()')[0]

        # 电影其他信息
        info = div.xpath('./div/div[@class="bd"]/p[1]/text()')[1].strip().split('/')
        time = sub(r'\s+', '', info[0])
        country = sub(r'\s+', '', info[1])
        movie_type = info[-1][1:].replace(' ', ',')

        # 评分
        score = div.xpath('./div/div[@class="bd"]/div/span[@class="rating_num"]/text()')[0]
        all_data.append([name, score, time, country, movie_type])

    # 3.保存数据
    writer.writerows(all_data)
    print(f'第{page//25}页数据下载完成!')


if __name__ == '__main__':
    writer = csv.writer(open('files/电影.csv', 'w', encoding='utf-8', newline=''))
    writer.writerow(['电影名称', '评分', '上映时间', '国家', '类型'])

    for x in range(0, 226, 25):
        t = Thread(target=get_page_data, args=(x, ))
        t.start()

5.阻塞

import time
from datetime import datetime
from threading import Thread, current_thread
from random import randint
# 定义download函数
def download(name):
    print(f'======{name}开始下载:{datetime.now()}======')
    time.sleep(randint(2, 7))
    print(f'======{name}下载结束:{datetime.now()}======')


if __name__ == '__main__':
    # 创建三个子线程分别下载三个电影
    # t1 = Thread(target=download, args=('肖申克的救赎',))
    # t2 = Thread(target=download, args=('霸王别姬',))
    # t3 = Thread(target=download, args=('阿甘正传',))

    # 案例1:三个电影同时开始下载,所有电影都下载结束后才打印"全部下载完成"
    # t1.start()
    # t2.start()
    # t3.start()
    #
    # # 1.线程对象.join()     -   让当前线程处于阻塞状态,直到指定线程对应的任务完成位置
    # t1.join()
    # t2.join()
    # t3.join()
    #
    # print('全部下载完成!')

    # 案例2: 等第1个电影下载完成,才同时下载第2个和第3个电影
    # t1.start()
    #
    # t1.join()
    # t2.start()
    # t3.start()

    # 练习:同时下载20部电影,电影1、电影2、电影3,....、电影20,要求所有电影都下载结束后打印 '全部下载完成!'
    ts = []
    for x in range(1, 21):
        name = f'电影{x}'
        t = Thread(target=download, args=(name,))
        t.start()
        ts.append(t)

    for t in ts:
        t.join()

    print('全部下载完成!')

6.获取豆瓣优化

import requests
from lxml import etree
from re import sub
import csv
from threading import Thread
def get_page_data(page):
    print(f'第{page//25}页数据开始下载')
    # 1.获取网页数据
    url = f'https://movie.douban.com/top250?start={page}&filter='
    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36',
        'cookie': 'bid=2L4tF88mhxQ; ll="118318"; dbcl2="222590700:FVo7RHfVAd4"; ck=P4n_; push_noty_num=0; push_doumail_num=0'
    }
    proxy = {
        'https': '119.7.145.186:4531',
        'http': '119.7.145.186:4531'
    }
    response = requests.get(url, headers=headers, proxies=proxy)
    print(response.text)

    # 2. 使用xpath解析数据
    root = etree.HTML(response.text)
    all_div = root.xpath('//ol[@class="grid_view"]/li/div')

    page_data = []
    for div in all_div:
        # 电影名字
        name = div.xpath('./div/div[@class="hd"]/a/span[1]/text()')[0]

        # 电影其他信息
        info = div.xpath('./div/div[@class="bd"]/p[1]/text()')[1].strip().split('/')
        time = sub(r'\s+', '', info[0])
        country = sub(r'\s+', '', info[1])
        movie_type = info[-1][1:].replace(' ', ',')

        # 评分
        score = div.xpath('./div/div[@class="bd"]/div/span[@class="rating_num"]/text()')[0]

        # 排名
        rank = div.xpath('./div/em/text()')[0]

        page_data.append([int(rank), name, score, time, country, movie_type])

    all_data.append((page, page_data))


if __name__ == '__main__':
    writer = csv.writer(open('files/电影.csv', 'w', encoding='utf-8', newline=''))
    writer.writerow(['排名','电影名称', '评分', '上映时间', '国家', '类型'])
    all_data = []

    ts = []
    for x in range(0, 226, 25):
        t = Thread(target=get_page_data, args=(x, ))
        t.start()
        ts.append(t)

    for t in ts:
        t.join()


    # all_data = [(页数, [[], [], [], []]), (页数, [[], [], [], []]), (页数, [[], [], [], []]),...]

    all_data.sort(key=lambda item: item[0])
    for x in all_data:
        writer.writerows(x[1])
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值