两周从爬虫小白变大神,看完你就知道我不是标题党了【五万字教程(1)

( ) 用于分组的符号

[ ] 指定匹配字符的范围,如 [a-c_B-F]

{ } 指定匹配的长度(量词表示)

  • 写出pymysql.Connect()连接数据库的核心参数

Connect(host,

port=3306,

user,

password,

db,

charset)

  • 豆瓣动作电影排行榜

  • 肯德基店铺位置


爬虫第二天


回顾知识点

核心的网络请求库 -> urllib库

  • urllib.request 模块

  • urlopen(url | request: Request, data=None) data是bytes类型

  • urlretrieve(url, filename) 下载url的资源到指定的文件

  • build_opener(*handlder) 构造浏览器对象

  • opener.open(url|request, data=None) 发起请求

  • Request 构造请求的类

data={

‘wd’: ‘’

}

urlencode(data) => ‘wd=%f5%e6%e6%f5%e6%e6’

request = Request(url, data=urlencode(data).encode())

  • HTTPHandler HTTP协议请求处理器

  • ProxyHandler(proxies={‘http’: ‘http://proxy_ip:port’}) 代理处理

  • HTTPCookieProcessor(CookieJar())

  • http.cookiejar.CookieJar 类

  • urllib.parse模块

  • quote(txt) 将中文字符串转成url编码

  • urlencode(query: dict) 将参数的字典转成url编码,结果是key=value&key=value形式,即以 application/x-www-form-urlencoded作为url编码类型。

requests库【重点】

requests库也是一个网络请求库, 基于urllib和urllib3封装的便捷使用的网络请求库。

安装环境

pip install requests -i https://mirrors.aliyun.com/pypi/simple

核心的函数

  • requests.request() 所有请求方法的基本方法

以下是request()方法的参数说明

  • method: str 指定请求方法, GET, POST, PUT, DELETE

  • url: str 请求的资源接口(API),在RESTful规范中即是URI(统一资源标签识符)

  • params: dict , 用于GET请求的查询参数(Query String params);

  • data: dict , 用于POST/PUT/DELETE 请求的表单参数(Form Data)

  • json: dict 用于上传json数据的参数, 封装到body(请求体)中。请求头的Content-Type默认设置为application/json

  • files: dict, 结构 {‘name’: file-like-object | tuple}, 如果是tuple, 则有三种情况:

  • (‘filename’, file-like-object)

  • (‘filename’, file-like-object, content_type)

  • (‘filename’, file-like-object, content_type, custom-headers)

指定files用于上传文件, 一般使用post请求,默认请求头的Content-Typemultipart/form-data类型。

  • headers/cookies : dict

  • proxies: dict , 设置代理

  • auth: tuple , 用于授权的用户名和口令, 形式(‘username’, ‘pwd’)

  • requests.get() 发起GET请求, 查询数据

可用参数:

  • url

  • params

  • json

  • headers/cookies/auth

  • requests.post() 发起POST请求, 上传/添加数据

可用参数:

  • url

  • data/files

  • json

  • headers/cookies/auth

  • requests.put() 发起PUT请求, 修改或更新数据

  • requests.patch() HTTP幂等性的问题,可能会出现重复处理, 不建议使用。用于更新数据

  • requests.delete() 发起DELETE请求,删除数据

requests.Respose

以上的请求方法返回的对象类型是Response, 对象常用的属性如下:

  • status_code 响应状态码

  • url 请求的url

  • headers : dict 响应的头, 相对于urllib的响应对象的getheaders(),但不包含cookie。

  • cookies: 可迭代的对象,元素是Cookie类对象(name, value, path)

  • text : 响应的文本信息

  • content: 响应的字节数据

  • encoding: 响应数据的编码字符集, 如utf-8, gbk, gb2312

  • json(): 如果响应数据类型为application/json,则将响应的数据进行反序化成python的list或dict对象。

  • 扩展-javascript的序列化和反序列化

  • JSON.stringify(obj) 序列化

  • JSON.parse(text) 反序列化

数据解析方式之xpath

xpath属于xml/html解析数据的一种方式, 基于元素(Element)的树形结构(Node > Element)。选择某一元素时,根据元素的路径选择,如 /html/head/title获取<title>标签。

绝对路径

从根标签开始,按tree结构依次向下查询。

如 /html/body/table/tbody/tr。

相对路径

相对路径可以有以下写法

  • 相对于整个文档

//img

查找出文档中所有的<img>标签元素

  • 相对于当前节点

//table

假如当前节点是<table>, 查找它的<img>的路径的写法

.//img

数据提取

  • 提取文本

//title/text()

  • 提取属性

//img/@href

位置条件

获取网页中的数据类型与字符集, 获取第一个<meta>标签

//meta[1]//@content

获取最后一个<meta>标签

//meta[last()]//@content

获取倒数第二个<meta>标签

//meta[position()-2]//@content

获取前三个<meta>标签

//meta[position()❤️]//@content

属性条件

查找 class为circle-img<img>标签

//img[@class=“circle-img”]

在Python中应用

安装包 pip install lxml

作业

  • 写出urllib库的请求处理器有哪些类(尽量写全路径)

  • urllib.request.HTTPHandler

  • urllib.request.HTTPCookieProcessor

  • urllib.request.ProxyHandler

  • 写出json.loads()和pickle.loads()返回的数据类型

  • json.loads() 返回list或dict, 加载的是字符串

  • pickle.loads() 返回是python中的对象, 加载的是字节数组 bytes

  • 写出pymysql的cursor.execute()方法中的参数及作用

  • 有两个参数, 一个是sql, 一个是args

  • args可以是tuple,对应sql字符串的 %s

  • args也可以是dict, 对应sql字符串的%(xxx)s, xxx是dict中的key

  1. 买家秀的模特的所有图片, 图片的名称是姓名-序号, 如’Disen-1.jpg’, ‘Disen-2.jpg’

  2. 中国图书网

爬虫所有的小说的基本信息(名称、作者、出版社、原价、折扣价、活动标签、 简介)

扩展

  • 在Ubuntu 下安装docker

  • 基于docker部署ElasticSearch搜索引擎库。

  • 基于requests实现索引库及文档的添加和查询。

爬虫第三天


回顾知识点

requests库

  • requests.request(method, url, **kwargs)

常用的参数

  • params/data/json 上传数据

  • files 上传文件

  • headers/cookies

  • proxies 代理服务器

  • auth 授权

  • requests.get(url, params, **kwargs)

  • requtests.post(url, data, json, **kwargs)

  • requests.put(url, data, json, **kwargs)

  • requests.delete(url, **kwargs)

  • requests.session() - > session对象, 可以调用 s.get()/post()/put()/delete()等方法,多次请求的会话(连接Session)是同一个

所有的请求返回的对象是requests.Response类的实例, 实例的属性:

  • status_code

  • headers

  • encoding

  • text/content

  • cookies

  • json() 反序列化json文本字符串为python的list或dict的对象

xpath解析

  • 路径写法

  • / 依次查找

  • // 间接查找

  • ./ 从当前元素下查找

  • .// 从当前元素的间接子节点查找

  • 位置条件

  • //li[1] 整个文档中的第一个<li>标签

  • //li[last()] 最后一个

  • //li[position() < 3] 前2个

  • //li[position() - 2] 倒数第2个

  • 属性条件

  • //li[@id="xxxx"]

  • //li[@class=""] @class 属性名

  • //li[@class="" and @name=""] 多个属性的且的关系

  • 同时提取两个元素

  • //title/text() | //img/@src

  • 模糊条件

  • //div[contains(@class, "page")] 查找class属性包含page的所有div标签

  • //div[starts-with(@class, "box")] 第一个class的属性值为box的div标签

  • //div[ends-with(@class, "clearfix")]最一个class的属性值为clearfix的div标签

扩展封装ES-SDK

“”"

基于requests库封装操作ElasticSearch搜索引擎的函数 (SDK)

“”"

from urllib.parse import quote

import requests

INDEX_HOST = ‘119.3.170.97’

INDEX_PORT = 80

class ESIndex():

“”“ES的索引库的类”“”

def __init__(self, index_name, doc_type):

self.index_name = index_name

self.doc_type = doc_type

def create(self):  # 创建索引库

url = f’http://{INDEX_HOST}:{INDEX_PORT}/{self.index_name}’

json_data = {

“settings”: {

“number_of_shards”: 5,

“number_of_replicas”: 1

}

}

resp = requests.put(url, json=json_data)

if resp.status_code == 200:

print(‘创建索引成功’)

print(resp.json())

def delete(self):  # 删除索引库

resp = requests.delete(f’http://{INDEX_HOST}:{INDEX_PORT}/{self.index_name}')

if resp.status_code == 200:

print(‘delete index ok’)

def add_doc(self, item: dict):

向库中增加文档

doc_id = item.pop(‘id’, None)

url = f’http://{INDEX_HOST}:{INDEX_PORT}/{self.index_name}/{self.doc_type}/’

if doc_id:

url += str(doc_id)

resp = requests.post(url, json=item)

if resp.status_code == 200:

print(f’{url} 文档增加成功!')

def remove_doc(self, doc_id):

删除文档

url = f’http://{INDEX_HOST}:{INDEX_PORT}/{self.index_name}/{self.doc_type}/{doc_id}’

resp = requests.delete(url)

if resp.status_code == 200:

print(f’delete {url} ok’)

def update_doc(self, item: dict):

更新文档

doc_id = item.pop(‘id’)

url = f’http://{INDEX_HOST}:{INDEX_PORT}/{self.index_name}/{self.doc_type}/{doc_id}’

resp = requests.put(url, json=item)

assert resp.status_code == 200

print(f’{url} update ok’)

def query(self, wd=None):

查询

q = quote(wd) if wd else ‘’

url = f’http://{INDEX_HOST}:{INDEX_PORT}/{self.index_name}/_search?size=100’

if q:

url += f’&q={q}’

resp = requests.get(url)

datas = []

if resp.status_code == 200:

ret = resp.json()

hits = ret[‘hits’][‘hits’]

if hits:

for item in hits:

data = item[‘_source’]

data[‘id’] = item[‘_id’]

datas.append(data)

return datas

if __name__ == ‘__main__’:

index = ESIndex(‘gushiwen’, ‘tuijian’)

index.create()

index.add_doc({

‘id’: 1,

‘name’: ‘disen’,

‘price’: 19.5

})

index.add_doc({

‘id’: 2,

‘name’: ‘jack’,

‘price’: 10.5

})

print(index.query())

正则解析数据

扩展Linux文件权限

100 ->4 -> r

010 -> 2-> w

001 -> 1 -> x

100 | 010 = 110 # 增加权限

110 & 100 == 100 # 验证100权限

110 ^ 100 = 010   # 删除100权限

re面试中的问题

  • compile() /match()/search() 三者之间的区别

  • search()/findall()区别

  • 贪婪模式和非贪婪模式

解析站长之家

“”"

基于正则re模块解析数据

“”"

import re

import os

import requests

from utils.header import get_ua

base_url = ‘http://sc.chinaz.com/tupian/’

url = f’{base_url}shuaigetupian.html’

headers = {

‘User-Agent’: get_ua()

}

if os.path.exists(‘mn.html’):

with open(‘mn.html’, encoding=‘utf-8’) as f:

html = f.read()

else:

resp = requests.get(url, headers=headers)

print(resp.encoding)  # IOS-8859-1

resp.encoding = ‘utf-8’  # 可以修改响应的状态码

assert resp.status_code == 200

html = resp.text

with open(‘mn.html’, ‘w’, encoding=resp.encoding) as f:

f.write(html)

print(html)

[\u4e00-\u9fa5]

compile = re.compile(r’(.\*?)')

compile2 = re.compile(r’(.\*?)')

imgs = compile.findall(html)  # 返回list

if len(imgs) == 0:

imgs = compile2.findall(html)

print(len(imgs), imgs, sep=‘\n’)

下一页

next_url = re.findall(r’20<a href=“(.*?)” class=“nextpage”',html, re.S)

print(base_url+next_url[0])

作业

  • 写出requests.request()方法常用的参数及参数类型

  • method: str 请求方法, 可以指定 get, post, put, delete, options

  • url : str 请求路径或api接口

  • params/data/json : dict 上传的请求参数及json或form的data数据

  • headers/cookie: dict 请求头或Cookie信息

  • files: dict 上传的文件信息

  • 写出正则的贪婪模式有哪些

  • .* 0或多个任意字符

  • .+ 1或多个任意字符

  • .?

  • .{n, } 至少n个以上的任意字符

  • .{n, m} 至少n个以上的任意字符

  • 写出str对象的常用方法(10+)

  • join()

  • split()

  • strip()

  • replace()

  • upper()

  • lower()

  • title()

  • index()/rindex()

  • find()/rfind()

  • insert()

  • just()/ljust()/rjust()

  • capitalize() # 每个单词的首字母大写

要求: 自动生成订单号

订单号的格式: 20191226000001

当天的单号按自增,第二天的序号是从1开始。

  • count()

  • encode()

  • startswith()/endswith()

  • format()

  1. 基于Flask实现文件上传服务器, 通过requests测试文件上传接口。

  2. 优化美女网爬虫,将数据存到es搜索引擎中

  3. 完成站长之家的多任务爬虫的数据存储(ES引擎/csv)

爬虫第四天


回顾知识点

re正则

  • 字符的表示

  • . 任意一个字符, 除了换行

  • [a-f] 范围内的任意一个字符

  • \w 字母、数字和下划线组成的任意的字符

  • \W

  • \d

  • \D

  • \s

  • \S

  • 量词(数量)表示

  • * 0或多个

  • + 1或多个

  • ? 0 或 1 个

  • {n} n 个

  • {n,} 至少n个

  • {n, m} n~m个

  • 分组表示

  • ( ) 普通的分组表示, 多个正则分组时, search().groups() 返回是元组

  • (?P<name> 字符+数量)带有名称的分组, 多个正则分组时,search().groupdict()返回是字典, 字典的key即是分组名。

import re

text = ‘123abc90ccc’

re.search(r’(?P\d+?)[a-z]+?(?P\d+)', text).groupdict()

  • Python中的正则模块

  • re.compile() 一次生成正则对象,可以多次匹配查询

  • re.match(正则对象, 字符串)

  • re.search()

  • re.findall()

  • re.sub()

re.sub(‘\d+’, ‘120’, text) # 将text中的所有数字替换成120

分享面试题:

给定列表,每一个元组中包含字母和数字, 要求字母和数字分开排序

如:

[‘abc12’, ‘abc9’, ‘abc10’, ‘ac8’, ‘ac12’]

排序之后结果是:

[‘abc9’, ‘abc10’, ‘abc12’, ‘ac8’, ‘ac12’]

def format_number(item):

replace_number = re.findall(r’\d+',item)[0].rjust(2, ‘0’)

return re.sub(r’\d+',replace_number,item)

arr = [‘abc12’, ‘abc9’, ‘abc10’, ‘ac8’, ‘ac12’]

sorted(arr, key=format_number)

  • re.split()

进程和线程

  • multiprocessing模块(进程)

  • Process 进程类

  • Queue 进程间通信的队列

  • put(item, timeout)

  • item = get(timeout)

  • threading 模块(线程)

  • Thread 线程类

  • 线程间通信(访问对象)

  • queue.Queue 线程队列

  • 回调函数(主线程声明, 子线程调用函数)

BS4数据解析

  • 安装包

pip install bs4

  • from bs4 import BeautifulSoup

  • 生成bs4根节点对象

root = BeautifulSoup(html, ‘lxml’)

  • 查找节点(bs4.element.Tag)

  • root.find(‘标签名’, class_=“”, id_=“”) 返回单节点Tag对象

  • root.find_all(‘标签名’, class_=“”, id_=“”, limit=3) 返回limit指定数量的Tag对象的列表

  • root.select(‘样式选择器’)

  • #id

  • .class

  • 标签名

  • [属性]

  • div ul 间接子节点, 或 div > ul直接子节点

  • 节点的属性

  • 获取文本数据

  • div.text/div.string/div.get_text()

  • 获取属性

  • div.get(‘属性名’)

  • div[‘属性名’]

  • div.attrs[‘属性名’]

  • div.attrs.get(‘属性名’)

  • 获取子节点

  • contents 获取所有文本子节点

  • descendants 获取所有子节点对象

协程爬虫

协程是线程的替代品, 区别在于线程由CPU调度, 协程由用户(程序)自己的调度的。协程需要事件监听模型(事件循环器),它采用IO多路复用原理,在多个协程之间进行调度。

协程的三种方式

  • 基于生成器 generator (过渡)

  • yield

  • send()

  • Python3 之后引入了 asyncio模块

  • @asyncio.coroutine 协程装饰器, 可以在函数上使用此装饰器,使得函数变成协程对象

  • 在协程函数中,可以使用yield from 阻塞当前的协程,将执行的权限移交给 yield from 之后的协程对象。

  • asyncio.get_event_loop() 获取事件循环模型对象, 等待所有的协程对象完成之后结束。

  • Python3.5之后,引入两个关键字

  • async 替代 @asyncio.coroutine

  • await 替代 yield from

协程第三方的框架

  • gevent

  • eventlet

  • Tornado/Twisted

动态js渲染

Selenium

Selenium是驱动浏览器(chrome, firefox, IE)进行浏览器相关操作(打开url, 点击网页中按钮功连接、输入文本)。

在Python程序中使用时,需要selenium的库和相关浏览的驱动程序(Window, Linux, Mac)。

Splash

Splash 是Web服务, 基于WebKit技术框架,可以动态加载网页。

作业

  • 写出生成dict对象的方式有哪些

  • { }

  • dict([(key, value), …])

  • json.loads(‘json格式的字符串’)

  • OrderDict

  • dict(zip([ ], [ ]))

  • dict.fromkeys([], value)

  • dict(key=value, key=value)

  • 写出bs4查找的节点对象的类是什么,它有哪些属性及方法

  • bs4.element.Tag/bs4.Tag 节点对象的类

  • Tag的方法

  • find()

  • find_all()

  • select()

  • get_text()

  • Tag的属性

  • string 标签的文本

  • text 标签的文本

  • contents 所有文本的子节点

  • descendants 所有的子节点对象

  • attrs 属性字典

  • 写出创建线程Thread类的实例时的参数有哪些

提示: Thread(参数列表)

  • name 线程名

  • target 线程执行的目标函数

  • args 函数中位置传参, tuple

  • kwargs 指定函数中关键参数传值 , dict

  • 使用docker搭建Splash服务

  • 股票信息提取

  • 腾讯公司招聘需求抓取

爬虫最五天


回顾知识点

协程的爬虫

  • 协程和线程区别

线程是CPU调度的,多线程是共享同一进程中的内存的(线程本地变量 Local、同步锁Lock、条件变量)。

线程是threading模块

协程是在线程(主)中声明及调度的。协程由用户(程序)调度的,是基于事件模型(IO多路复用模型-select/poll/epoll)。

协程是asyncio模块(Python 3.4+)

  • 协程的知识点

  • @asyncio.coroutine 将函数升级为协程对象(闭包函数)

  • yield from 将执行的权限移交给其它协程对象

  • loop = asyncio.get_event_loop() 获取事件模型

  • loop.run_until_complete(协程对象) 事件模型启动协程,直到协程执行完成后,释放事件模型对象。

  • 如果是多个协程对象时, 需要使用asyncio.wait() 将多个协程对象以元组方式传入到wait()方法中。

  • Python 3.5+增加两个关键字

  • async 替代@asyncio.coroutine

  • await 替代 yield from

注意: async 和 await 必须同时使用

Seleinum库

  • 安装python库

pip install selenium

  • 下载浏览器的驱动

  • chrome

  • firefox

  • 在Python中使用

  • selenium.webdriver.common.by.By

  • By.CLASS_NAME

  • By.CSS_SELECTOR

  • By.ID

  • By.NAME

  • By.TAG_NAME

  • By.XPATH

  • By.LINK_TEXT

  • selenium.webdriver.Chrome

  • 在实例化Chrome()对象中, 需要指定driver.exe浏览驱动程序的位置。如果位置在环境变量的Path添加了,则不需要指定位置参数。

  • chrome.get(url) 打开url

  • chrome.find_element(by, value) 根据by 查找value的一个元素。

  • chrome.find_elements(by, value) 查找多个元素

  • chrome.window_handlers: list 可以获取窗口标签页

  • chrome.execute_script(js) 当前窗口中执行js脚本

  • chrome.swich_to.window/frame() 切换窗口

  • chrome.close()

  • chrome.page_source 渲染之后的html网页源码

  • WebElement 是查找元素的对象类型

  • click() 点击

  • send_keys() 输入内容

  • 等待WebElement元素出现

  • selenium.webdriver.support 模块

  • ui

  • WebDriverWait(driver, timeout)

  • until(expected_conditions, err_msg)

  • expected_conditions

  • visibility_of_all_elements_located((By, value))

Chrome-headless

options = Options()

options.add_argument(‘–headless’)

options.add_argument(‘–disable-gpu’)

options.binary_location=r’/Users/apple/PycharmProjects/xpy905_spider/day04/chromedriver’

chrome = Chrome(options=options)

headless 无窗口

Splash渲染

下载镜像

通过docker下载splash镜像

官方服务器

sudo docker pull scrapinghub/splash

私有的docker仓库下载

sudo docker pull 10.36.173.95:5000/splash

启动镜像

sudo docker run -itd --name splash-s -p 8050:8050 10.36.173.95:5000/splash

-p 指定宿主机和容器的端口映射关系,

格式: [宿主机端口]:[容器的端口]

-d 后台启动, -t 可以打开容器的终端, -i 可进入容器

进入容器

sudo docker exec -it splash-s bash

未进入容器时,也可以通过exec命令执行容器中的命令

sudo docker exec splash-s ls -l

ls -l 命令会列出splash-s容器当前的目录下的所有文件。

render.html接口

渲染动态js的接口: http://ip:port/render.html

接口的参数:

  • url 目标的网址

  • wait 等待渲染或加载的时间

  • proxy

  • headers

  • timeout

如,渲染jd.com网页

http://10.36.173.186:8050/render.html?url=https://jd.com

自动化测试

单元测试

Pythonu单元测试模块-unittest

from unittest import TestCase

class TestIndex(TestCase):

def setUp(self):

print(‘–测试前的资源准备工作—’)

def test_a_add_index(self):

print(‘–添加索引–’)

data[‘index_name’] = ‘person_sos’

def test_b_query_index(self):

print(‘–查询索引–’)

def test_c_delete_index(self):

print(‘–删除索引–’)

def tearDown(self):

print(‘–测试后的资源回收工作—’)

集成测试

单元测试套件 unitest.TestSuit

“”"

使用单元测试,测试ES搜索引擎的RESTful接口

  • requests

  • unittest

“”"

from unittest import TestCase, TestSuite, TextTestRunner

data = {

}

class TestDoc(TestCase):

def test_a2_add_doc(self):

print(f’-{data[“index_name”]}-增加doc文档–')

def test_a3_query_doc(self):

print(f’-{data[“index_name”]}-查询doc文档–')

if __name__ == ‘__main__’:

必须以普通的Python脚本运行

suite = TestSuite()

suite.addTest(TestIndex.test_a_add_index)

suite.addTest(TestDoc.test_a2_add_doc)

suite.addTest(TestDoc.test_a3_query_doc)

TextTestRunner().run(suite)

作业

  • 写出Python协程的模块及核心函数

  • 写出Selenium的查找元素的方式

  • 写出Python获取命令行参数的方式


爬虫第六天


回顾知识点

爬虫的认知

- 数据请求(网络请求库)

  • 数据解析(re/xpath/bs4)

  • 数据存储(csv/pymysql/json??)

  • 反反爬的策略

  • ip代理

  • ua池

  • cookie池: 收集手动登录之后的响应的Cookie信息

  • 请求间隔(2~5秒)

  • 验证码处理(打码平台、机器学习???)

网络请求库

- urllib

  • request

  • urlopen()

  • urlretrieve(fullurl, filename)

  • Request(url, data=None, headers)

  • build_opener(*handlers)

  • HTTPHandler

  • HTTPCookieProcessor(http.cookiejar.CookieJar())

  • ProxyHandler(proxies={})

  • parse

  • quote()

  • urlencode()

  • http.client.HTTPResponse

  • code

  • getheaders()

  • getheader(name, default)

  • read() 读取的响应字节数据

  • requests (第三方)

  • request(method, url, params, data, json, files, headers, cookies, proxies, auth)

  • get(url, params, **kwargs)

  • post(url, data, json, **kwargs)

  • put(url, data, json, **kwargs)

  • delete(url, **kwargs)

  • Response

  • status_code

  • encoding

  • headers

  • content 字节数据

  • text 文本数据

  • json() json文本反序列化为Python的dict/list的对象

数据解析

- re

  • xpath (pip install lxml)

  • from lxml import etree

root = etree.HTML(html)

root.xpath(‘’) # list[‘’] / list[, ]

  • 返回文本列表的xpath表示

  • @href/@src 标签属性

  • text() 标签文本

  • 返回Element元素列表

  • //title

  • //ul/li[1]

  • bs4 (pip install bs4)

  • from bs4 import BeautifulSoup

root = BeautifulSoup(html, ‘lxml’) # bs4.element.Tag

  • 查询元素标签的方法

  • find(‘标签名’, class_, id_) 查找第一个

  • find_all(‘标签名’, class_, id_, limit=N) 查找前N个

  • select(‘css选择器’)

  • #id

  • .classname

  • 标签名

  • 后代标签

  • 兄弟标签 (查找多个标签)

  • 属性标签

  • 伪类

  • Tag属性

  • string/text

  • get_text()

  • attrs: dict 标签中所有属性的字典

  • contents 子标签的文本列表

  • descendants 子标签的Tag列表

多任务爬虫

  • 多线程

  • threading

  • Thread

  • queue.Queue 线程队列

  • 多进程

  • multiprocessing

  • Process

  • Queue 进程队列

  • 协程

  • asyncio

  • coroutine 协程装饰器

  • get_event_loop()

  • wait()

  • sleep()

  • yield from

  • async / await

selenium框架

以driver程序驱动浏览器,对目标(网站或网页)进行操作(请求网页、提取数据、截图、切换或关闭页签-window)。

- chrome.get() 打开目标(发起请求)

  • chrome.quit() 退出浏览器

  • chrome.close() 关闭当前的窗口

  • chrome.find_element(By, value)

  • selenium.webdriver.common.by.By

  • ID

  • CLASS_NAME

  • NAME

  • XPATH

  • CSS_SELECTOR

_ LINK_TEXT

  • WebElement 查到的标签对象

  • get_attribute(‘属性名’, default)

  • text 标签文本

  • click()

  • send_keys()

  • rect 当前元素的位置(left, top, width, height)

  • chrome.find_elements(By, value)

  • execute_script()

  • save_screenshot(filename) 截图

  • 等待某一个标签元素出现

  • selenium.webdriver.support

  • ui

  • WebDriverWait

  • expected_conditions

  • visibility_of_all_elements_located((By, value))

ui.WebDriverWait(dirver, timeout).until(

expected_conditions,

error_msg

)

docker

容器技术,将远程的docker仓库中的镜像下拉到本地, 再将镜像运行成为一个容器(进程)。

- 镜像操作

  • 基本信息

  • 名称

  • 版本

  • ID

  • 描述

  • docker images 查看所有镜像

  • docker rmi 名称:版本号 / ID 删除镜像

  • docker run 名称:版本号 / ID 启动镜像

  • -dit 后台启动镜像,启动后可进入容器并打开新的terminal(终端)

  • -p 宿主机端口: 容器端口

  • 容器操作

  • docker ps 查看正运行的容器

  • -a 查看所有的容器

  • -l 查看最后一个启动的容器

  • docker logs 容器名或ID 查看容器运行的日志

  • docker exec 容器名或ID Linux命令 在容器中执行Linux命令

  • docker exec -it 容器名或ID bash 进入容器

  • docker stop 容器名或ID

  • docker start 容器名或ID

  • docker restart 容器名或ID

  • docker rm -f 容器名或ID 删除容器, -f强制删除正运行的容器

日志模块进阶

日志格式

| 格式 | 说明 |

| — | — |

| %(name)s | 记录器的名称, 默认为root |

| %(levelno)s | 数字形式的日志记录级别 |

| %(levelname)s | 日志记录级别的文本名称 |

| %(filename)s | 执行日志记录调用的源文件的文件名称 |

| %(pathname)s | 执行日志记录调用的源文件的路径名称 |

| %(funcName)s | 执行日志记录调用的函数名称 |

| %(module)s | 执行日志记录调用的模块名称 |

| %(lineno)s | 执行日志记录调用的行号 |

| %(created)s | 执行日志记录的时间 |

| %(asctime)s | 日期和时间 |

| %(msecs)s | 毫秒部分 |

| %(thread)d | 线程ID |

| %(threadName)s | 线程名称 |

| %(process)d | 进程ID |

| %(message)s | 记录的消息 |

- Python脚本中执行当前操作系统的命令的方法

  • os.chdir() 切换当前目录

  • os.system() 无返回结果 (打开一个子进程执行 命令)

  • os.popen() 可读取返回结果

日志模块的核心

  • 四大核心

  • 日志记录器 Logger

  • 日志处理器Handler

  • 日志的过滤器Filter

  • 日志的格式化Formatter

scrapy框架

scrapy架构组成

  • 五个核心

  • engine 引擎, 协调其它四个组件之间的联系,即与其它四个组件进行通信,也是scrapy框架的核心。

  • spider 爬虫类, 爬虫程序的编写代码所在, 也是发起请求的开始的位置。spider发起的请求,经过engine转入到scheduler中。

  • scheduler 调度器, 调度所有的请求(优先级高,则会先执行)。当执行某一个请求时,由engine转入到downloader中。

  • donwloader 下载器, 实现请求任务的执行,从网络上请求数据,将请求到的数据封装成响应对象,并将响应的对象返回给engine。engine将数据响应的数据对象(以回调接口方式)回传给它的爬虫类对象进行解析。

  • itempipeline 数据管道, 当spider解析完成后,将数据经engine转入到此(数据管道)。再根据数据类型,进行数据处理(图片、文本)

  • 二个中间件

  • 爬虫中间件, 介于Spider和Engine之间的,可以拦截Spider的发起的请求及数据。

  • 下载中间件,介于Engine和Downloader之间的,可以拦截下载和响应。当然在下载处理之前,可以设置代理 、请求头、Cookie等操作(反反爬设置),还可以基于Splash或Selenium实现特定的操作。

scrapy指令

  • 创建项目命令

  • scrapy startproject 项目名称

  • 创建爬虫命令

  • scrapy genspider 爬虫名 域名

  • 启动爬虫命令

  • scrapy crawl 爬虫名

  • 调试爬虫命令

  • scrapy shell url

  • scrapy shell

  • fetch(url)

Response类

  • 属性相关【重点】

  • body 响应的字节数据

  • text 响应的编码之后文本数据

  • headers 响应头信息, 是字节数据

  • encoding 响应数据的编码字符集

  • status 响应的状态码

  • url 请求的url

  • request 请求对象

  • meta 元数据,用于request和callback回调函数之间传值

  • 解析相关【重点】

  • selector()

  • css() 样式选择器 , 返回Selector选择器的可迭代(列表)对象

  • scrapy.selector.SelectorList 选择器列表

  • x()/xpath()

  • scrapy.selector.Selector 选择器

  • 样式选择器提取属性或文本

  • ::text 提取文本

  • ::attr("属性名") 提取属性

  • xpath() xpath路径

xpath路径,同lxml的xpath()写法

  • 选择器常用方法

  • css()/xpath()

  • extract() 提取选择中所有内容,返回是list

  • extract_first()/get() 提取每个选择器中的内容, 返回是文本

Request类

  • scrapy.http.Request

请求对象的属性

  • url

  • callback 解释数据的回调函数对象

  • headers 请求头

  • priority 请求的优先级, 值越高,优先级越高(优先下载)

作业

  • 写出selenium向下和向右滚动的脚本

document.documentElement.scrollTop 向下

document.documentElement.scrollLeft 向右

  • 写出restful接口设计规范(四个)

  • 每个资源都有唯一标识 URI

  • 每个资源具有四个动作, GET|POST|PUT|DELETE

  • 每次请求都是无状态

  • 接口交互的数据是json或xml

  • 写出常见的反爬虫和反反爬虫

  • 访问次数 - IP代理

  • Cookie验证- Cookie池

  • UA验证 - UA池

  • 验证码 - 打码平台

  • 动态js渲染 - Selenium/Splash

  • 爬取 陕西省政府采购网 陕西省采购网

  • 基于Flask实现日志上报服务器(日志微服务)

  • logging.handlers.HTTPHandler

爬虫第七天


回顾知识点

日志模块

import logging

from logging import StreamHandler, FileHandler

  • 四个核心部分

  • 日志记录器logger: 记录日志信息

  • 日志处理器 handler: 记录信息之后,由handler去处理

  • 日志过滤器 filter: 对记录信息进行过滤。

  • 日志格式化 formatter: 由处理器对记录的信息按formatter格式进行处理(除HTTPHandler和SMTPHandler之外)。

  • 核心方法或函数

  • logging.getLogger(name) # 默认没有name时,返回root

  • logging.baseConfig() 配置root记录器的格式、处理器等。

  • logging.info()/debug()/warning()/error()/critical() 由root记录器记录日志信息。

  • logger记录器的核心方法

  • setLevel(logging.DEBUG|INFO|WARNING|ERROR|FATAL)

  • addHandler(handler)

  • addFilter(Filter)

  • debug()|info()….

  • handler处理器的核心方法

  • setLevel(logging.DEBUG|INFO|WARNING|ERROR|FATAL)

  • setFormatter(fmt)

  • Formatter初始化参数

  • format 格式化的字符串, 使用%(日志变量)s 相关日志变量占位符组成的字符串

‘hi, %(name)s, age is %(age)s’ % {‘age’: 20, ‘name’: ‘jack’}

‘hi, %s, age is %s’ % (‘disen’, 30)

  • datefmt 指定 %(asctime)s 日志时间的格式, 通常使用 %Y-%m-%d %H:%M:%S年月日 时分秒格式。

scrapy框架

五大组件两个中间件

  • engine 核心引擎

  • spider 爬虫类

  • scheduler 调度器

  • downloader 下载器

  • itempipeline 数据管道

  • 爬虫中间件、下载中间件

scrapy指令

  • scrapy startproject 项目名

  • scrapy genspider 爬虫名 域名

  • scrapy crawl 爬虫名

  • -o 保存数据到指定的文件中

  • -s 信号(CLOSESPIDER_ITEMCOUNT=30)

  • scrapy shell [url]

  • fetch(url)

  • view(response)

  • request: scrapy.http.Request

  • response: scrapy.http.Response|HtmlResponse

  • scrapy

Response对象的属性或方法

  • body|text|encoding|status|url|request|headers|meta

  • xpath()|css() -> scrapy.selector.SelectorList[Selector]

  • extract()

  • get()

  • extract_first()

  • css() 中表达式

  • 样式选择器[::text|attr("属性名")]

  • xpath()中表达式

同lxml的xpath表达式相同。

Request初始化参

  • url

  • callback 如果未指定,则默认为 parse

  • priority 优先级的权限值, 值高优先级高

  • meta

  • headers

  • dont_filter 是否过滤重复的url, True不过滤,Flase过滤.

scrapy数据管道

指令方式存储

scrapy crawl 爬虫名 -o xxx.json|csv

只适合单页数据爬取,如果多页多层次数据爬取时,不适合此方式。

Item类

作用: 用于区别中哪一页(类型)的数据

用法: 类似于dict用法, 在数据管道类的process_item()方法中,通过isinstance()方法来判断item是哪一类型的。

import scrapy

class BookItem(scrapy.Item):

book_id = scrapy.Field()

book_name = scrapy.Field()

book_cover = scrapy.Field()

book_url = scrapy.Field()

author = scrapy.Field()

tags = scrapy.Field()

summary = scrapy.Field()

class SegItem(scrapy.Item):

book_id = scrapy.Field()

seg_id = scrapy.Field()  # 章节ID

title = scrapy.Field()

url = scrapy.Field()

class SegDetailItem(scrapy.Item):

seg_id = scrapy.Field()  # 章节ID

content = scrapy.Field()  # 内容

Pipeline

  • 处理数据的方法

def process_item(self, item, spider):

return item

  • item参数表示 爬虫类中解释到的数据(yield item)

  • spider参数 表示爬虫类对象

  • 如果item被返回,则表示可以被优先级低的pipeline处理

  • 初始化方法

属于定制方法,可以初始化一些参数或对象,如文件名, 数据库的连接等。

  • process_iteminit的调用次数说明

  • process_item方法 会被(engine)多次调用

  • init随着爬虫程序的启动时创建pipeline类时调用,只会被调用一次

定量爬虫

基于信号方式

scrapy crawl -s 信号

常用的scrapy信号

  • **CLOSESPIDER_ITEMCOUNT=**条目的数量

  • CLOSESPIDER_PAGECOUNT=请求页的数量

  • CLOSESPIDER_ERRORCOUNT=请求错误的数量

  • CLOSESPIDER_TIMEOUT=超时的时长

scrapy crawl wanben -s CLOSESPIDER_ITEMCOUNT=10

下载中间件

爬虫中间件

监测爬虫类与引擎之间的交互数据(请求 request、响应 response、数据item)及异常情况

@classmethod

def from_crawler(cls, crawler): pass  # 启动爬虫时用于创建爬虫中间件类的实例对象

def process_spider_input(self, response, spider) # 流程中第6步,engine将请求响应的数据输入给spider时,调用此方法。

def process_spider_output(self, response, result, spider) # 流程中第7步,由spider类解析response数据之后产生结果输出给engine时,调用此方法

def process_spider_exception(self, response, exception, spider): # 解析数据时发异常时

def process_start_requests(self, start_requests, spider): # 第一次爬虫发起请求时,调用此方法,即流程中第1步,从Spider->Engine时。

下载中间件 [重点]

下载中间件是引擎engine和下载器downloader之间的中间件,可以拦截请求和响应以及请求异常的处理。

@classmethod

def from_crawler(cls, crawler)

def process_request(self, request, spider)

def process_response(self, request, response, spider)

def process_exception(self, request, exception, spider)

  • **process_request()**方法可返回的对象(四种可能)

  • scrapy.http.Request

  • scrapy.http.HtmlResponse/Response

  • None 表示不拦截

  • raise IgnoreRequest 不下载这个请求

  • **process_response()**方法可以返回的对象

  • scrapy.http.Request 未下载成功请求

  • scrapy.http.Response 进一步封装之后的response

4.3 作用

在下载中间件中,可以设置代理、设置cookie、设置请求头以及基于Selenium实现动态js渲染和用户登录。

作业

  • 写出scrapy的工作流程中第3、6两个步骤的描述

第3步: 引擎从调度器中获取下载任务, scheduler -> engine

第6步: 引擎从下载器获取的响应传递给spider, 用于解析。engine-> spider。 ( response.request.callback(response) )

  • 写出logging.baseConfig()方法的参数(4+)

logging.baseConfig(filename,  # 文件处理器参数

mode=“a”,  # 文件处理器参数

format,    # formatter

datefmt,   # formatter

handlers,  # addHandler(),

filters,   # addFilter()

stream)    # filename设置后, stream无效

  • 根据左边AA表结构和右边的查询结果,写出查询的SQL

---------------------------       ----------------------

| year | month | amount |       | year | m1 |   m2 |

---------------------------       ----------------------

| 1991 |   1   | 1.1   |       | 1991 | 1.1 | 1.2 |

---------------------------       ----------------------

| 1991 |   2   | 1.2   |       | 1992 | 2.1 | 2.2 |

---------------------------       ----------------------

| 1992 |   1   | 2.1   |


| 1992 |   2   | 2.2   |


  • join连接表方式

select a1.year, a1.amount as m1, a2.amount as m2

from AA a1

一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面。

img
img

二、Python必备开发工具

工具都帮大家整理好了,安装就可直接上手!img

三、最新Python学习笔记

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。

img

四、Python视频合集

观看全面零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

img

五、实战案例

纸上得来终觉浅,要学会跟着视频一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。img

六、面试宝典

在这里插入图片描述

在这里插入图片描述

简历模板在这里插入图片描述

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python爬虫全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:python)
img

间件类的实例对象

def process_spider_input(self, response, spider) # 流程中第6步,engine将请求响应的数据输入给spider时,调用此方法。

def process_spider_output(self, response, result, spider) # 流程中第7步,由spider类解析response数据之后产生结果输出给engine时,调用此方法

def process_spider_exception(self, response, exception, spider): # 解析数据时发异常时

def process_start_requests(self, start_requests, spider): # 第一次爬虫发起请求时,调用此方法,即流程中第1步,从Spider->Engine时。

下载中间件 [重点]

下载中间件是引擎engine和下载器downloader之间的中间件,可以拦截请求和响应以及请求异常的处理。

@classmethod

def from_crawler(cls, crawler)

def process_request(self, request, spider)

def process_response(self, request, response, spider)

def process_exception(self, request, exception, spider)

  • **process_request()**方法可返回的对象(四种可能)

  • scrapy.http.Request

  • scrapy.http.HtmlResponse/Response

  • None 表示不拦截

  • raise IgnoreRequest 不下载这个请求

  • **process_response()**方法可以返回的对象

  • scrapy.http.Request 未下载成功请求

  • scrapy.http.Response 进一步封装之后的response

4.3 作用

在下载中间件中,可以设置代理、设置cookie、设置请求头以及基于Selenium实现动态js渲染和用户登录。

作业

  • 写出scrapy的工作流程中第3、6两个步骤的描述

第3步: 引擎从调度器中获取下载任务, scheduler -> engine

第6步: 引擎从下载器获取的响应传递给spider, 用于解析。engine-> spider。 ( response.request.callback(response) )

  • 写出logging.baseConfig()方法的参数(4+)

logging.baseConfig(filename,  # 文件处理器参数

mode=“a”,  # 文件处理器参数

format,    # formatter

datefmt,   # formatter

handlers,  # addHandler(),

filters,   # addFilter()

stream)    # filename设置后, stream无效

  • 根据左边AA表结构和右边的查询结果,写出查询的SQL

---------------------------       ----------------------

| year | month | amount |       | year | m1 |   m2 |

---------------------------       ----------------------

| 1991 |   1   | 1.1   |       | 1991 | 1.1 | 1.2 |

---------------------------       ----------------------

| 1991 |   2   | 1.2   |       | 1992 | 2.1 | 2.2 |

---------------------------       ----------------------

| 1992 |   1   | 2.1   |


| 1992 |   2   | 2.2   |


  • join连接表方式

select a1.year, a1.amount as m1, a2.amount as m2

from AA a1

一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面。

img
img

二、Python必备开发工具

工具都帮大家整理好了,安装就可直接上手!img

三、最新Python学习笔记

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。

img

四、Python视频合集

观看全面零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

img

五、实战案例

纸上得来终觉浅,要学会跟着视频一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。img

六、面试宝典

在这里插入图片描述

在这里插入图片描述

简历模板在这里插入图片描述

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python爬虫全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:python)
[外链图片转存中…(img-UFJjEvzb-1711209441152)]

  • 30
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值