爬虫总结(day2—day7)

news/2024/11/13 3:59:42/

day2 requests和bs4

from uuid import uuid1              # 可以创建一个唯一的id值# 例:
open(f'files/{uuid1()}.jpeg'

浏览器伪装

import requestsheaders = {'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
}
response = requests.get('https://movie.douban.com/top250', headers=headers)print(response.text)

bs4数据解析

导入解析相关类

from bs4 import BeautifulSoup

bs4的用法

  • 1.准备需要解析的数据(获取网页数据)

    html = open('files/test.html', encoding='utf-8').read()
    
  • 2.基于网页源代码创建BeautifulSoup对象

    # soup对象代表网页对应的html标签(代表整个网页)
    soup = BeautifulSoup(html, 'lxml')
    
  • 3.获取标签

    # soup.select(css选择器)   -   在整个网页中获取css选择器选中的所有标签,返回值是一个列表,列表中元素是标签对象
    # soup.select_one(css选择器)   -   在整个网页中获取css选择器选中的第一个标签,返回值是标签对象
    result = soup.select('#box1 p')
    print(result)       # [<p>肖生克的救赎</p>, <p>霸王别姬</p>, <p>阿甘正传</p>]result = soup.select_one('#box1 p')
    print(result)       # <p>肖生克的救赎</p># 标签对象.select(css选择器)       -       在指定标签中获取css选择器选中的所有标签,返回值是一个列表,列表中元素是标签对象
    # 标签对象.select_one(css选择器)   -       在指定标签中获取css选择器选中的第一个标签,返回值是标签对象
    result = soup.select('p')
    print(result)       # [<p>肖生克的救赎</p>, <p>霸王别姬</p>, <p>阿甘正传</p>, <p>我是段落1</p>]box2 = soup.select_one('#box2')
    result = box2.select('p')
    print(result)       # [<p>我是段落1</p>]
    
  • 4.获取标签内容和标签属性

    p = soup.select_one('p')            #  <p>肖生克的救赎</p>
    img = soup.select_one('img')# a. 获取标签内容: 标签对象.text
    print(p.text)       # '肖生克的救赎'# b.获取标签属性值: 标签对象.attrs[属性名]
    print(img.attrs['src'], img.attrs['alt'])
    

day3 数据接口和selenium基础

爬虫时第一件事就是去看看有没有数据接口,因为这个可以直接获得数据,最简单,没有再考虑其他方法

import requestsresponse = requests.get('https://game.gtimg.cn/images/lol/act/img/js/heroList/hero_list.js')result = response.json()for x in result['hero']:print(x['name'])

补充:创建文件夹

import osif not os.path.exists('所有英雄的皮肤/abc'):    # 判断是否存在该文件夹os.mkdir('所有英雄的皮肤/abc')              # 没有该文件夹就创建文件夹

例:获取lol所有英雄皮肤图片

import requests
import os# 1.获取所有英雄的id
def get_all_hero_id():url = 'https://game.gtimg.cn/images/lol/act/img/js/heroList/hero_list.js'res = requests.get(url).json()return [x['heroId'] for x in res['hero']]def get_one_hero_skins(hero_id: str):# 1. 请求指定英雄对应的数据url = f'https://game.gtimg.cn/images/lol/act/img/js/hero/{hero_id}.js'res = requests.get(url)result = res.json()# 2. 创建这个英雄对应的文件夹hero_name = result['hero']['name']if not os.path.exists(f'所有英雄的皮肤/{hero_name}'):os.mkdir(f'所有英雄的皮肤/{hero_name}')# 3. 下载这个英雄所有的皮肤# 1)遍历拿到每个皮肤的名称和地址for skin in result['skins']:skin_name = skin['name'].replace('/', '')     # 防止皮肤名称中出现'/'skin_img = skin['mainImg']if not skin_img:skin_img = skin['chromaImg']# 2) 下载一张图片res = requests.get(skin_img)with open(f'所有英雄的皮肤/{hero_name}/{skin_name}.jpg', 'wb') as f:f.write(res.content)print('下载完成!')if __name__ == '__main__':ids = get_all_hero_id()for x in ids[:5]:get_one_hero_skins(x)

selenium基本用法

from selenium.webdriver import Chrome

基本步骤:

# 1. 创建浏览器对象(浏览器对象如果是全局变量,浏览器不会自动关闭)
b = Chrome()# 2. 打开网页(你需要爬的数据在哪个网页里面,就打开哪个网页)
b.get('https://movie.douban.com/top250')# 3. 获取网页源代码(获取到的一定是页面中加载出来的)
print(b.page_source)# 4. 关闭浏览器
b.close()

selenium控制浏览器的基本行为

from selenium.webdriver import Chrome
from time import sleep                   # 暂停
b = Chrome()
b.get('https://www.jd.com')# 1. 输入框输入内容
# 1)找到输入框
input_tag = b.find_element_by_id('key')
# 2)输入框输入内容
input_tag.send_keys('电脑\n')sleep(2)
print(b.page_source)         # 获取网页源代码# 2. 点击按钮
# 1)找到需要点击的标签
btn = b.find_element_by_css_selector('#navitems-group2 .b')
# 2)点击标签
btn.click()input('是否结束:')
b.close()

例:京东商品

from selenium.webdriver import Chrome
from time import sleep
from bs4 import BeautifulSoup
import csvb = Chrome()
b.get('https://www.jd.com')input_tag = b.find_element_by_id('key')
input_tag.send_keys('毛线\n')sleep(1)all_data = []
# 解析第一页数据
soup = BeautifulSoup(b.page_source, 'lxml')
all_goods_div = soup.select('#J_goodsList>ul>li>div.gl-i-wrap')
for x in all_goods_div:name = x.select_one('.p-name em').textprice = x.select_one('.p-price i').textall_data.append([name, price])# 点击下一页
next_btn = b.find_element_by_class_name('pn-next')
next_btn.click()
sleep(1)# 解析第二页数据
soup = BeautifulSoup(b.page_source, 'lxml')
all_goods_div = soup.select('#J_goodsList>ul>li>div.gl-i-wrap')
for x in all_goods_div:name = x.select_one('.p-name em').textprice = x.select_one('.p-price i').textall_data.append([name, price])writer = csv.writer(open('files/毛线.csv', 'w', encoding='utf-8', newline=''))
writer.writerows(all_data)input('结束:')
b.close()

切换选项卡(以爬中国知网为例)

from selenium.webdriver import Chrome
from time import sleep
from bs4 import BeautifulSoup# 1. 基本操作
b = Chrome()                        # 创建浏览器
b.get('https://www.cnki.net/')      # 打开中国知网
search_tag = b.find_element_by_id('txt_SearchText')     # 获取输入框
search_tag.send_keys('数据分析\n')      # 输入框输入'数据分析',然后按回车
sleep(1)        # 切换界面最后做一个等待操作# 获取需要点击的所有标签: 如果拿到标签后需要点击或者输入,必须通过浏览器获取标签
all_result = b.find_elements_by_css_selector('.result-table-list .name>a')
# 点击第一个结果(这儿会打开一个新的选项卡)
all_result[0].click()
sleep(1)# 2. 切换选项卡
# 注意:selenium中,浏览器对象(b)默认指向一开始打开的选项卡,除非用代码切换,否则浏览器对象指向的选项卡不会变
# 1)获取当前浏览器上所有的窗口(选项卡): 浏览器.window_handles
# 2)切换选项卡
b.switch_to.window(b.window_handles[-1])# 3)解析内容
soup = BeautifulSoup(b.page_source, 'lxml')
result = soup.select_one('#ChDivSummary').text
print(result)b.close()           # 关闭当前指向的窗口(最后一个窗口),窗口关闭后,浏览器对象的指向不会发生改变# 回到第一个窗口,点击下一个搜索结果
b.switch_to.window(b.window_handles[0])
all_result[1].click()
sleep(1)b.switch_to.window(b.window_handles[-1])soup = BeautifulSoup(b.page_source, 'lxml')
result = soup.select_one('#ChDivSummary').text
print(result)b.close()input('结束:')
b.close()

day3小结:

from selenium.webdriver import Chromeb = Chrome()
b.get('https://www.baidu.com')print(b.page_source)# 输入框输入内容
input_tag = b.find_element_by_id('kw')
input_tag.send_keys('Python')# 点击标签
btn = b.find_element_by_id('su')
btn.click()# 获取当前所有的窗口
all_windows = b.window_handles# 切换选项卡(切换窗口)
b.switch_to.window(all_windows[-1])

day4 selenium滚动和常见反爬

页面滚动:

  • 执行滚动操作——执行js中鼓动代码: window.scrollBy(x方向偏移量, y方向偏移量)

    # b.execute_script('window.scrollBy(0, 1800)')
    for x in range(10):b.execute_script('window.scrollBy(0, 700)')sleep(1)
    
from selenium.webdriver import Chrome
from time import sleep
from bs4 import BeautifulSoupb = Chrome()
b.get('https://www.jd.com')
b.find_element_by_id('key').send_keys('电脑\n')
sleep(1)# 1. 执行滚动操作  -  执行js中鼓动代码:  window.scrollBy(x方向偏移量, y方向偏移量)
# b.execute_script('window.scrollBy(0, 1800)')
for x in range(10):b.execute_script('window.scrollBy(0, 700)')sleep(1)soup = BeautifulSoup(b.page_source, 'lxml')
goods_li = soup.select('#J_goodsList>ul>li')
print(len(goods_li))input('关闭:')
b.close()

requests的自动登录:

# 自动登录原理:人工在浏览器上完成登录操作,获取登录后的cookie信息(登录信息),再通过代码发送请求的时候携带登陆后的cookieimport requestsheaders = {'cookie': '_zap=0fd5115d-0d5d-4ed0-b45e-2adb70d4f339; d_c0="APDRX-OEUxWPTqjePOGOljYO3swFC_QzNPs=|1659162124"; Hm_lvt_98beee57fd2ef70ccdd5ca52b9740c49=1659162125; _xsrf=381ec5b8-da42-4f05-8e28-d19cf6d6a398; __snaker__id=SX0kKbLxUiod9aY2; gdxidpyhxdE=f18LcdKX%2B%5Ct8tio3MP%2BD1OD84%2BRApcU3qwbA4niNAHbHVnQwjt78bwtg50Sh29X31070wSng1A1tEohclOOP%2F0Uu%2BByfY3yk9r%2BaLVfkEDyCR52a%2Fnjw9%2B5xD8SR3%5CVNiLgblEzelmOe%2BURMd3cwvR%2BbaViIbyibb4DBxh5x%2F4n6Nc3d%3A1660620145098; _9755xjdesxxd_=32; YD00517437729195%3AWM_NI=j0lqXMpiVT9Ft1ecXdzH2vYBBfxrLSQboKmgMuaJ66yH4f8tQCalk9yUDv0a8eE8mMtywVk0gO6gVWBgK6LkGyWD%2BqbFdDe28nanJKDs2W5iK9HS3%2BdWElcrykvCSASkZDM%3D; YD00517437729195%3AWM_NIKE=9ca17ae2e6ffcda170e2e6ee8cc76dadbe9e83f270abb88bb7d85e869b9bacc1548ea8a888ae72bcb9afa4f12af0fea7c3b92aaaf0a492db47b4b79ab5bc4eb8efab84db70ba98fe97dc4a82bab893cf5993bea1acf06d8fabafabb53ebb98fc87bb80939daf8dea33bb8b8c97b36bfcbb8bd9f047b8a7b9b7ea3ca591fa88d55d82b985d7cf6185a799a5aa7ba29aaca5e83afcb2af8fc94188adfeb8b86389e788b4b221a8898b8de27abbb5baa4d24b91b596a5d037e2a3; YD00517437729195%3AWM_TID=Izr5wPvl%2FL5EVBFFQUKVCMghk730wLD7; captcha_session_v2=2|1:0|10:1660619252|18:captcha_session_v2|88:dzZNa1dJaWRUSkl2TUJXVFFoNDBHajhNeDFrbVE5Z2V0VVRxRXF4RVdTeWpUTkx1UjdIWXMrY0wralFqWHUwRQ==|aa82afb586e24ed3b5a356d386bc47615c602de3501df5452adb052719815806; captcha_ticket_v2=2|1:0|10:1660619486|17:captcha_ticket_v2|704:eyJ2YWxpZGF0ZSI6IkNOMzFfYmxDenNOTy5DLUt1Vkdjb0dPcFI1d3FwUFVjbzlEeFVhNFhWTXFsVVdhWU5RZFhGa1o1QTBHd3NKODBReFlsUFFKYm5senI0RWhhVjVPUm1ySVp6c3FCODhDWVQ4RnlzSjlkY1hqcU55SDBLZlQxZDlUTmFhTGg4VVFkaVpEOXVaRUFtYWJ2S0IxRnhka2M2Z1Q0TUt2REVqWnFuYzlvV2dUSTg4cnFTeEdlLm9RYXk1NnYwbFgyMThxSjFZMjBrVXhUU182a1hXbG5DWHU3TFJaLVEyeEhOU2d3Ti1oZkpMLVd2ek03dEpyUkZReS5ZdGVJSm52YXBoRmFaZEFjRnR3RlJGLnhnTzZMT2RvLWtpQlVNR2VZb3FSejl0Wk84b2FDdUVlUXJjZmdodTlXQkhhNVBZVHAwTGg3RUp2Q283Lml0MG44bkRIU1ExSmlIWHYySUhZanFEWFNxZFU2Z1owNnYua2ZOUHI5MU51ZUg2Q3VESEtna2k2SmluVEdrZ2ZscG41WnVFYVM3dXlNZDhlTmxwMi0xMksxc3J5QXVnY2RXZjBsQ3JoWHhsNHFZODlEU1JhOXlVLWFUZ3gyYTY3Vk10dXFaU1hZYXNoNkwuSnFQdHR6eG5EQmR5QlNQS2piLW1wZnRqQnFfVzJyLjJ2QU1hU1JjVWdyMyJ9|7b8f8989f066c76bcbcceba0c8e948ded0199bb00266b625fa833b1d4f0cd6bc; z_c0=2|1:0|10:1660619509|4:z_c0|92:Mi4xaW5CWUdRQUFBQUFBOE5GZjQ0UlRGU1lBQUFCZ0FsVk45VmpvWXdCUHhFMEhGbEdrd2ZWeVk5dkNLOWZSXzBwQlVn|830d143f08bf6b012c5e9f19c0cc28c7285806a022a20c8d94627f0ce298a332; q_c1=4ad0f707d86d41e18e81833e6e23ae69|1660619510000|1660619510000; NOT_UNREGISTER_WAITING=1; tst=r; SESSIONID=YyOGVECIZRFPF2t7do835wkUei8LfraOIUNduLlfWNC; KLBRSID=57358d62405ef24305120316801fd92a|1660619789|1660619244','user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
}response = requests.get('https://www.zhihu.com/', headers=headers)
print(response.text)

selenium获取cookies

from selenium.webdriver import Chrome
from json import dumpsb = Chrome()# 1. 打开需要完成自动登录的网站(需要获取cookie的网站)
b.get('https://www.taobao.com/')# 2. 给足够长的时间让人工完成自动登录并且人工刷新出登录后的页面
# 强调:一定要把第一个页面刷新出登录之后的状态
input('已经完成登录:')# 3. 获取登录后的cookie并且将获取到的cookie保存到本地文件
cookies = b.get_cookies()
print(cookies)with open('files/taobao.txt', 'w', encoding='utf-8') as f:f.write(dumps(cookies))

selenium使用cookies

from selenium.webdriver import Chrome
from json import loadsb = Chrome()# 1. 打开需要自动登录网页
b.get('https://www.taobao.com/')# 2. 添加cookie
with open('files/taobao.txt', encoding='utf-8') as f:content = f.read()cookies = loads(content)for x in cookies:b.add_cookie(x)# 3. 重新打开需要登录的网页
b.get('https://www.taobao.com/')

requests使用代理基本用法

import requests# 119.7.146.192:4531headers = {'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
}# 1. 创建代理对应的字典
# 方法1:
# proxies = {
#     'http': '119.7.146.192:4531',
#     'https': '119.7.146.192:4531'
# }
# 方法2:
proxies = {'http': 'http://119.7.146.192:4531','https': 'http://119.7.146.192:4531'
}response = requests.get('https://movie.douban.com/top250', headers=headers, proxies=proxies)print(response.text)

requests使用代理实际用法

import requests
from time import sleepdef get_ip():url = 'http://d.jghttp.alicloudecs.com/getip?num=1&type=1&pro=&city=0&yys=0&port=11&time=2&ts=0&ys=0&cs=0&lb=4&sb=0&pb=4&mr=1&regions='while True:response = requests.get(url)if response.text[0] == '{':print('提取ip失败,重试!')sleep(1)continuereturn response.textdef get_douban_film():headers = {'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'}ip = get_ip()print(ip)proxies = {'http': ip,'https': ip}response = requests.get('https://movie.douban.com/top250', headers=headers, proxies=proxies)print(response.text)if __name__ == '__main__':get_douban_film()

day5 selenium高级和实战

selenium使用代理IP

from selenium.webdriver import Chrome, ChromeOptions# 1. 创建配置对象
options = ChromeOptions()
# 2. 添加配置
options.add_argument('--proxy-server=http://42.54.95.139:4531')# 3.通过指定配置创建浏览器对象
b = Chrome(options=options)b.get('https://movie.douban.com/top250')

selenium基本配置

from selenium.webdriver import Chrome, ChromeOptionsoptions = ChromeOptions()
# 1.取消测试环境
options.add_experimental_option('excludeSwitches', ['enable-automation'])# 2. 取消图片加载
options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})b = Chrome(options=options)
b.get('https://www.jd.com')

selenium等待

  • 1.隐式等待

    # 1.隐式等待
    """
    如果没有设置隐式等待:在通过浏览器获取标签的时候,如果标签不存在会直接报错;如果设置了隐式等待:在通过浏览器获取标签的时候,如果标签不存在会直接报错,不会马上报错,
    而是在指定时间范围内不断尝试重新获取标签,直到获取到标签或者超时为止(如果超时会报错);一个浏览器只需要设置一次隐式等待时间,它会作用于这个浏览器每次获取标签的时候。
    """options = ChromeOptions()
    options.add_experimental_option('excludeSwitches', ['enable-automation'])
    options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})b = Chrome(options=options)
    b.get('https://www.jd.com')# 1) 设置隐式等待时间
    b.implicitly_wait(5)
    print('=====')
    # 2) 获取标签的时候隐式等待时间才会生效
    input_tag = b.find_element_by_id('key')
    input_tag.send_keys('钱包\n')
    
  • 2.显示等待

    # 2. 显示等待  -  等到某个条件成立或者不成立为止
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.common.by import By
    """
    1)创建等待对象: WebDriverWait(浏览器对象, 超时时间)
    2)添加等待条件:
    等待对象.until(条件)      -   等到条件成立为止
    等待对象.until_not(条件)      -       等到条件不成立为止条件的写法:
    presence_of_element_located(标签)             -       指定标签出现
    text_to_be_present_in_element_value(标签, 值)         -      指定标签的value属性值中包含指定值
    text_to_be_present_in_element(标签, 值)               -      指定标签的标签内容中包含指定值注意:条件中提供标签的方式
    (By.xxx, 具体的值)
    """
    wait = WebDriverWait(b, 10)
    # wait.until(EC.text_to_be_present_in_element_value((By.ID, 'key'), '电脑'))
    # print('继续执行')# 等到页面中出现id值为J_goodsList里面class值为gl-i-wrap的div标签为止
    wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#J_goodsList div.gl-i-wrap')))print(b.page_source)
    

day6 lxml和多线程

1.xpath的基本概念

1)树:整个html(xml)代码结构就是一个树结构
2)节点:树结构中的每一个元素(标签)就是一个节点
3)根节点(根元素): html或者xml最外面的那个标签(元素)
4)节点内容:标签内容
5)节点属性:标签属性

2.xml数据格式

xml和json一样,是一种通用的数据格式(绝大部分编程语言都支持的数据格式)

3.xpath语法

  • 1)创建树结构获取树的根节点

    # etree.XML(xml数据)
    # etree.HTML(html数据)
    f = open('files/data.xml', encoding='utf-8')
    root = etree.XML(f.read())
    f.close()
    
  • 2)根据xpath获取指定标签

    节点对象.xpath(路径):返回路径对应的所有的标签,返回值是列表,列表中的元素是标签对象(节点对象)

    """
    路径的写法:
    1. 绝对路径:   用"/"开头的路径  -   /标签在树结构中的路径    (路径必须从根节点开始写)
    2. 相对路径:   路径开头用"."标签当前节点(xpath前面是谁,'.'就代表谁), ".."表示当前节点的上层节点
    3. 全(任意)路径:     用"//"开头的路径  -   在整个树中获取标签注意:绝对路径和全路径的写法以及查找方式和是用谁去点的xpath无关
    """
    result = root.xpath('/supermarket/staffs/staff/name/text()')
    print(result)result = root.xpath('./staffs/staff/name/text()')
    print(result)staff1 = root.xpath('./staffs/staff')[0]            # 获取第一个员工对应的staff标签
    result = staff1.xpath('./name/text()')
    print(result)       # ['小明']result = staff1.xpath('../staff/name/text()')
    print(result)       # ['小明', '小花', '张三', '李四', '王五']result = root.xpath('//name/text()')
    print(result)result = staff1.xpath('//goods/name/text()')
    print(result)
    
  • 3)获取标签内容

    节点对象.xpath(获取标签的路径/text()):获取指定路径下所有标签的标签内容

    result = root.xpath('//position/text()')
    print(result)
    
  • 4)获取标签属性值

    节点对象.xpath(获取标签的路径/@属性名)

    result = root.xpath('/supermarket/@name')
    print(result)       # ['永辉超市']result = root.xpath('//staff/@id')
    print(result)
    
  • 5)谓语(条件)

    a.位置相关谓语

    b.属性相关谓语

    c.子标签内容相关谓语

    # a. 位置相关谓语
    """
    [N]     -      第N个
    [last()]    -   最后一个
    [last()-N];   [last()-1] -  倒数第2个 、 [last()-2] - 倒数第3个
    [position()>N]、[position()<N]、[position()>=N]、[position()<=N]
    """
    result = root.xpath('//staff[1]/name/text()')
    print(result)       # ['小明']result = root.xpath('//staff[last()]/name/text()')
    print(result)       # ['王五']result = root.xpath('//staff[last()-1]/name/text()')
    print(result)       # ['李四']result = root.xpath('//staff[position()<3]/name/text()')
    print(result)   # ['小明', '小花']# b.属性相关谓语
    """
    [@属性名=属性值]      -      指定属性是指定值的标签
    [@属性名]      -   拥有指定属性的标签
    """
    # staff[@class="c1"] == staff.c1
    result = root.xpath('//staff[@class="c1"]/name/text()')
    print(result)result = root.xpath('//staff[@id="s003"]/name/text()')
    print(result)result = root.xpath('//goods[@discount]/name/text()')
    print(result)# c.子标签内容相关谓语       -    根据子标签的内容来筛选标签
    """
    [子标签名>数据]
    [子标签名<数据]
    [子标签名>=数据]
    [子标签名<=数据]
    [子标签名=数据]
    """
    result = root.xpath('//goods[price=2]/name/text()')
    print(result)
    
  • 6)通配符:写路径的时候用*来表示所有标签或者所有属性

    result = root.xpath('//staff[1]/*/text()')
    print(result)# *[@class="c1"]  == .c1
    result = root.xpath('//*[@class="c1"]/name/text()')
    print(result)result = root.xpath('//goods[@*]/name/text()')
    print(result)result = root.xpath('/supermarket/@*')
    print(result)
    
  • 7)若干路径 —— |

    # 路径1|路径2       -      同时获取路径1和路径2的内容
    result = root.xpath('//goods/name/text()|//staff/position/text()')
    print(result)
    

多线程

1.基本理论

1)进程和线程
进程:  一个正在运行的应用程序就是一个进程,每个进程均运行在其专门且受保护的内存空间中
线程: 线程是进程执行任务的基本单元(一个进程中的任务都是在线程中执行的)进程就是车间,线程就是车间里面的工人。
一个进程中默认有一个线程,这个线程叫主线程。2)线程的特点
如果在一个线程中执行多个任务,任务是串行执行的。
(当一个程序中有很多个任务的时候,如果只有一个线程,那么程序的执行效率会很低)3)多线程
一个进程中有多个线程就是多线程。
多线程执行任务的时候,多个任务可以同时(并行)执行。4)多线程原理
一个cpu同一时间只能调度一个线程,多线程其实是cpu快速的在多个线程之间进行切换,造成多个线程同时执行的假象。
(提高cpu利用率)

2.python使用多线程的方法

一个进程默认只有一个线程,这个线程叫主线程,主线程以外的线程都叫子线程。
Python程序中如果需要子线程,必须创建线程类(Thread)的对象。

from threading import Thread
from time import sleep
from datetime import datetimedef download(name):print(f'{name}开始下载:{datetime.now()}')sleep(2)print(f'{name}下载结束:{datetime.now()}')if __name__ == '__main__':# 情况1:在一个线程(主线程)中下载3个电影# download('肖生克救赎')# download('霸王别姬')# download('阿甘正传')# 情况2:使用3个子线程分别下载3个电影# 1)创建线程对象"""线程对象 = Thread(target=函数, args=元组)a.函数  - 可以是普通函数函数名,也可以是匿名函数。这个函数就是需要子线程中执行的任务。b.元组  - 元组中的元素就是在子线程中调用target对应的函数的时候需要的参数"""t1 = Thread(target=download, args=('肖生克救赎',))t2 = Thread(target=download, args=('霸王别姬',))t3 = Thread(target=download, args=('阿甘正传',))# 2)启动线程 - 让子线程调用对应的函数t1.start()t2.start()t3.start()

day7 线程池和指令系统

线程等待(阻塞)

from threading import Thread
from time import sleep
from datetime import datetime
from random import randintdef download(name):print(f'{name}开始下载:{datetime.now()}')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:前两个电影都下载完成后才下载第三个电影t1.start()t2.start()t1.join()t2.join()t3.start()

线程池

1.线程池——管理多个线程的工具

线程池工作原理:先创建指定个数的线程,然后添加多个任务(任务数量>线程数量),让线程池中的线程去执行添 加的所有任务,直到所有任务都执行完(线程池中的每个线程可能会执行多个任务)

from threading import Thread, current_thread
from time import sleep
from datetime import datetime
from random import randint
from concurrent.futures import ThreadPoolExecutordef download(name):print(f'{name}开始下载:{datetime.now()}', current_thread())sleep(randint(2, 7))print(f'{name}下载结束:{datetime.now()}')if __name__ == '__main__':# 方案1:直接使用多线程下载1000个电影# num = 0# for _ in range(10):#     ts = []#     for x in range(100):#         num += 1#         t = Thread(target=download, args=(f'电影{num}',))#         ts.append(t)#         t.start()#     for x in ts:#         x.join()# 方案2:使用线程池下载1000个电影# 1. 创建线程池# ThreadPoolExecutor(线程数最大值)pool = ThreadPoolExecutor(3)# 2. 添加任务# 1) 一次添加一个任务: submit(函数, 实参1, 实参2, 实参3,...)# 注意:实参的数量由前面的函数在调用的时候需要的实参来决定pool.submit(download, '肖生克的救赎')pool.submit(download, '霸王别姬')# 2)同时添加多个任务: map(函数, 参数对应的序列)# 注意:使用map添加多个任务的时候,任务对应的函数必须是有且只有一个参数的函数pool.map(download, ['V字仇杀队', '恐怖游轮', '沉默的羔羊'])# 3. 关闭线程池# 线程池关闭后无法再添加新的任务,并且会阻塞当前线程等待整个线程池的任务都完成pool.shutdown()print('==============完成!=============')

常用的指令操作

常见的指令操作 执行指令的工具: Windows - 命令提示符(cmd) 、Mac - 终端1. 运行python程序:  -  运算程序的计算机必须先安装python环境   win:    python  py文件路径     
mac:  python3  py文件路径     2. 进入文件夹:  cdcd  文件夹相对路径、文件夹绝对路径注意:如果是windows操作系统,cd操作如果要跨盘需要先切盘,然后再cd切盘方法:C:、E:、D:3. 查看当前文件夹的内容win:  dirMac:ls4. 用指令创建虚拟环境第一步:找到一个用来放虚拟环境的文件夹第二步:通过cd指令进入到存放虚拟环境的文件夹中第三步:创建虚拟环境python    -m    venv    虚拟环境名python3    -m   venv   虚拟环境名第四步:激活虚拟环境(mac) source  虚拟环境目录/bin/activate(windows)  虚拟环境目录\ Scripts\activate.bat第五步:退出虚拟环境deactivate5.常用pip指令(pip - Python包管理工具)pip list      -     查看当前环境已经安装过的所有的第三方库pip install  第三方库名称       -     下载并且安装指定的第三方库pip install  第三方库名称 -i 镜像地址       -     在指定的镜像地址中下载安装pip install  第三方库名称==版本号   -i   镜像地址pip install  第三方库名称1   第三方库名称2  pip freeze > 依赖文件名     -  生成依赖文件 pip install -r 依赖文件路径        -     批量安装   pip uninstall 第三方库名称   -  卸载指定的第三方库

http://www.ppmy.cn/news/336958.html

相关文章

kubernetes 存储卷

文章目录 8. kubernetes 存储卷一、简介二、基本存储1. EmptyDir资源配置文件 2. HostPath资源配置文件 3. NFSNFS实现3.1 搭建NFS网络存储系统3.2 将NFS网络系统与kubernetes相结合资源配置文件 三、高级存储1. PV准备NFS环境资源配置文件 2. PVC创建PVCpod使用PVC 3. PV 、 P…

Javaweb安全——Shiro漏洞利用

炒个冷饭&#xff0c;主要还是对反序列化漏洞利用方式的学习&#xff0c;目前只测试了tomcat环境&#xff0c;后面再将weblogic的部分补一补。 Shiro反序列化 SHIRO-550 漏洞编号&#xff1a;CVE-2016-4437 / CNVD-2016-03869 / SHIRO-550 影响版本&#xff1a;shiro 1.x <…

微信支付V3版商家转账到零钱

微信支付V3版商家转账到零钱 在对接微信中作为技术小白&#xff0c;可真是煞费苦心呀&#xff0c;特此参考了大佬文档&#xff0c;和微信文档进行开发。特意记录一下&#xff0c;以便在工作中遗忘。 操作步骤&#xff1a; 登录微信支付商户平台-产品中心&#xff0c;开通商家…

echarts 地图_地图 json 免费下载_自定义icon

Echarts 常用各类图表模板配置 注意&#xff1a; 这里主要就是基于各类图表&#xff0c;更多的使用 Echarts 的各类配置项&#xff1b; 以下代码都可以复制到 Echarts 官网&#xff0c;直接预览&#xff1b; 图标模板目录 Echarts 常用各类图表模板配置一、地图二、环形图三、…

ML:文本、图像等数值化数据相似度计算之余弦相似度计算三种python代码实现

ML:文本、图像等数值化数据相似度计算之余弦相似度计算三种python代码实现 目录 相似度计算之余弦相似度计算 输出结果 三种python代码实现

飞机动力学模型推导

飞机动力学模型推导 针对最一般刚性假设下飞机动力学模型进行推导&#xff0c;未进行线性化处理 1. 坐标系 包含地轴系、体轴系、航迹轴系、气流轴系等 &#xff0c;详见航空飞行动力学一书&#xff0c;此处不予赘述。 2.基本假设 关于地球基本假设&#xff1a; 1、略去地…

Kubernetes Host网络模式应用(可获取真实IP)

在实际生产环境中&#xff0c;有些容器内应用&#xff08;比如编码器&#xff09;需要用到物理层面的网络资源&#xff08;比如组播流&#xff09;。这就要求Kubernetes中的该Pod以HOST模式来启动。以下实验了Kubernetes-HOST网络模式&#xff0c;并给出了一些运维建议。 一、…

html学习笔记

iframe里有一个srcdoc属性&#xff0c;很有用&#xff01; window.location.hrefdocument.referrer//可以实现返回上一级页面并刷新 HTML5权威指南©&#xff0c;比较老的书了&#xff0c;有些知识过时了&#xff01;&#xff01;&#xff01; HTML5高级程序设计 也是比较老…