day27作业
from selenium.webdriver import Chrome,ChromeOptions
from multiprocessing import Process
from selenium.webdriver.common.keys import Keys
import time,csv
from lxml import etree
options = ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-automation'])
options.add_experimental_option('prefs', {'profile.managed_default_content_settings.images':2})
def product_name(name):
b = Chrome(options=options)
b.get('https://www.jd.com')
res=b.find_element_by_id('key')
res.send_keys(name)
res.send_keys(Keys.ENTER)
time.sleep(10)
height=200
for x in range(20):
b.execute_script(f'window.scrollTo(0,{height})')
height+=200
time.sleep(15)
analyse_data(b.page_source,name)
def analyse_data(b,u):
if u=='男装':
result=[]
html=etree.HTML(b)
# color=html.xpath('//div[@id="J_goodsList"]/ul/li/div/div[2]/div/ul/li/a/@title')
price=html.xpath('//div[@id="J_goodsList"]/ul/li/div/div[3]/strong/i/text()')
introduction=html.xpath('//div[@id="J_goodsList"]/ul/li/div/div[4]/a/@title')
count=html.xpath('//div[@id="J_goodsList"]/ul/li/div/div[5]/strong/a/text()')
for h,d in enumerate(price):
s = csv.writer(open(f'jdfiles/{u}.csv', 'w', encoding='utf-8', newline=''))
if not introduction[h]:
introduction[h]='暂无简介信息'
if not count[h]:
count[h]='暂无评论人数信息'
h=[price[h],introduction[h],count[h]]
result.append(h)
s.writerow(['价格', '简介', '评论人数'])
s.writerows(result)
elif u=='手机':
result = []
html = etree.HTML(b)
# color = html.xpath('//div[@id="J_goodsList"]/ul/li/div/div[2]/div/ul/li/a/@title')
price = html.xpath('//div[@id="J_goodsList"]/ul/li/div/div[3]/strong/i/text()')
introduction = html.xpath('//div[@id="J_goodsList"]/ul/li/div/div[4]/a/@title')
count = html.xpath('//div[@id="J_goodsList"]/ul/li/div/div[5]/strong/a/text()')
for h, d in enumerate(price):
s = csv.writer(open(f'jdfiles/{u}.csv', 'w', encoding='utf-8', newline=''))
if not introduction[h]:
introduction[h]='暂无简介信息'
if not count[h]:
count[h]='暂无评论人数'
h = [price[h], introduction[h], count[h]]
result.append(h)
s.writerow(['价格', '简介', '评论人数'])
s.writerows(result)
if __name__ == '__main__':
product=['男装','手机']
for x in product:
p = Process(target=product_name, args=(x,))
p.start()
学习总结:
# 1. 什么是进程 - 工厂
"""
一个正在运行的应用程序就是一个进程。
每一个进程均运行在其专用且受保护的内存(运行内容)中
"""
# 2. 什么是线程 - 工厂里面的工人
"""
线程是进程执行任务的基本单元。
进程要做什么事情,或者要干什么活必须要有线程。
"""
# 3. 线程的特点 - 串行
"""
如果要在一个线程中执行多个任务,任务是串行执行(一个一个的按照顺序执行)
"""
# 4. 多线程
"""
默认情况下一个进程只有一个线程(一个工厂只有一个工人),多线程指的是在一个进程中有多个线程(一个工厂有多个工人)。
多线程执行不同的任务可以并行(同时)执行。
注意:多线程可以提高程序执行效率,但不是线程越多越好。(计算机一般的应用程序不要超过100个,爬虫可以到达200到300个)
"""
from threading import Thread, current_thread
from datetime import datetime
import time
# 1. 主线程和子线程
# 一个进程默认只有一个线程,这个线程叫主线程。除了主线程以外的线程都叫子线程。
# 如果进程中需要子线程,只能自己创建(创建线程类或者线程类的子类对象)。
print(current_thread()) # <_MainThread(MainThread, started 4605672896)>
def download(name):
print(f'{name}开始下载:{datetime.now()}')
time.sleep(2)
print(f'{name}下载结束:{datetime.now()}')
# 2. 单线程的串行
# download('午夜凶铃')
# download('上海堡垒')
# download('沉默的羔羊')
# 3.创建三个子线程,下载三部电影
# 1)1)创建线程对象
"""
创建线程对象,并且分配线程任务: Thread(*, target, args)
target - 需要在子线程中调用的函数,需要给一个普通函数的函数名(代表任务)
args - 在子线程中调用target对应的函数的时候需要的参数对应的元组。
如果需要一个实参,元组就给一个元素,如果需要两个实参,元组就给两个元素,...
"""
t1 = Thread(target=download, args=('午夜凶铃',))
t2 = Thread(target=download, args=('上海堡垒',))
t3 = Thread(target=download, args=('沉默的羔羊',))
# 2)启动线程: 线程对象.start()
t1.start()
t2.start()
t3.start()
from selenium.webdriver import Chrome
import time
from lxml import etree
from threading import Thread
import requests
import os
from datetime import datetime
b = Chrome()
def download_image(url):
print(f'开始下载.....:{datetime.now()}')
res = requests.get(url)
image_name = os.path.basename(url)
open(f'files/{image_name}', 'wb').write(res.content)
print(f'图片下载完成!{datetime.now()}')
def get_html():
# 1. 获取图片地址
b.get('https://stock.tuchong.com/topic?topicId=50346')
time.sleep(1)
html = etree.HTML(b.page_source)
result = html.xpath('//div[@class="justified-layout"]/div/div/@data-lazy-url')
# 2. 下载图片
print('==================开始下载===================')
for img_url in result:
t = Thread(target=download_image, args=('https:'+img_url,))
t.start()
if __name__ == '__main__':
get_html()
from datetime import datetime
import time
from random import randint
from threading import Thread
# 1. 阻塞线程 - 等到某个线程的任务结束才接着执行
# 线程对象.join()
def download(name):
print(f'{name}开始下载:{datetime.now()}')
time.sleep(randint(2, 7))
print(f'{name}下载结束:{datetime.now()}')
# =========================华丽的分割线===============================
# t1 = Thread(target=download, args=('肖申克的救赎',))
# t2 = Thread(target=download, args=('触不可及',))
# t3 = Thread(target=download, args=('头脑特工队',))
# t4 = Thread(target=download, args=('恐怖游轮',))
# 需求1: 等到四个电影都下载完成(四个子线程都结束)才打印'电影全部下载完成'
# t1.start()
# t2.start()
# t3.start()
# t4.start()
#
# t1.join()
# t2.join()
# t3.join()
# t4.join()
# print('============电影全部下载完成===============')
# 需求2:第1个电影下载完成后才开始下载第2、3、4个电影
# t1.start()
# t1.join()
#
# t2.start()
# t3.start()
# t4.start()
# =========================华丽的分割线===============================
names = ['肖申克的救赎', '触不可及', '头脑特工队', '恐怖游轮']
ts = []
for name in names:
t = Thread(target=download, args=(name,))
t.start()
ts.append(t)
for t in ts:
t.join()
# 要求: 所有电影都下载结束打印 '全部下载完成'
print('=============全部下载完成=============')
import requests
from threading import Thread
from bs4 import BeautifulSoup
import csv
def get_one_page(url):
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'
}
res = requests.get(url, headers=headers)
soup = BeautifulSoup(res.text, 'lxml')
all_li = soup.select('ol.grid_view>li')
page_data = []
for li in all_li:
name = li.select_one('.title').text
score = li.select_one('.rating_num').text
page_data.append([name, score])
# 方案一:获取完一页数据就往文件中写一页数据
# writer.writerows(page_data)
# 方案二:获取完一页数据后将数据添加到保存所有数据的大列表中
all_data.extend(page_data)
print('======一页数据获取完成=====')
if __name__ == '__main__':
# 1. 创建csv文件对应的writer
writer = csv.writer(open('files/豆瓣电影2.csv', 'w', encoding='utf-8', newline=''))
writer.writerow(['名字', '评分'])
# 方案二:
all_data = []
# 2. 多线程下载数据
urls = [f'https://movie.douban.com/top250?start={x}&filter=' for x in range(0, 250, 25)]
ts = []
for url in urls:
t = Thread(target=get_one_page, args=(url,))
t.start()
ts.append(t)
for t in ts:
t.join()
print('===================全部完成====================')
# 方案二:
all_data.sort(key=lambda item: float(item[-1]), reverse=True)
writer.writerows(all_data)
from multiprocessing import Process
from datetime import datetime
import time
# 1. 多进程
"""
一个应用程序默认只有一个进程(主进程),每一个进程中默认有一个线程(主线程);
一个程序可以有多个进程(除了主进程以外的进程叫子进程),任何一个进程中又可以有多个线程。
如果希望程序中有子进程,需要自己创建进程对象(创建的进程中都自带一个线程)
"""
# 2. 使用多进程
def download(name):
print(f'{name}开始下载:{datetime.now()}')
time.sleep(2)
print(f'{name}下载结束:{datetime.now()}')
# 注意:如果想要使用多进程,必须在程序中添加这个if语句
if __name__ == '__main__':
# 1)创建进程对象
p1 = Process(target=download, args=('肖生克的救赎',))
p2 = Process(target=download, args=('惊魂记',))
p3 = Process(target=download, args=('7号房的礼物',))
# 2)启动进程
p1.start()
p2.start()
p3.start()
# 3)进程阻塞
p1.join()
p2.join()
p3.join()
print('下载完成!')
import time
from selenium.webdriver import Chrome, ChromeOptions
from multiprocessing import Process
from selenium.webdriver.common.keys import Keys
options = ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-automation'])
options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})
def get_one_goods(name):
b = Chrome(options=options)
b.get('https://www.jd.com')
search = b.find_element_by_id('key')
search.send_keys(name)
search.send_keys(Keys.ENTER)
time.sleep(30)
if __name__ == '__main__':
goods = ['运动鞋', '笔记本电脑']
for x in goods:
p = Process(target=get_one_goods, args=(x,))
p.start()