爬虫的步骤(精简 复盘版)
-
-
爬虫是否违法
- 法不禁止即为许可
- 隐匿自己的身份(商业IP代理)
- 不要被目标网站举证有破坏动产行为
- 尽量遵守爬虫协议(robots.txt)
-
-
爬虫的分类和作用
- 通用爬虫 —> 搜索引擎
- 定向爬虫 —> 有具体的爬取目标
对中小企业来说,数据一定是短板,要么花钱买数据,要么写爬虫 国家机器和很多的互联网产品做舆情监控基本也是通过网络爬虫来
-
爬虫怎么写?
-
抓取页面(
requests / aiohttp
)response = requests.get(url, headers= , pyoies=) # (网站, 请求头, 代理)
-
解析页面
-
正则表达式解析(
re库
)~ compile() ---> 返回一个Pattern --- 创建正则对象 ~ search() / match() ---> Match ---> group() ---- 找一个 ~ findall() ---> 返回一个list --- 找全部
-
XPath解析 — (
lxml库中的etred
)~ 右键菜单“检查” ---> Copy ---> Copy full XPath
-
CSS选择器解析(
beautifulsoup4 / pyquery
)soup = BeautifulSoup(html, 'lxml') - select():获取跟CSS选择器匹配的元素(列表) - select_one():获取跟CSS选择器匹配的第一个元素 ---> Tag ~ text:获取标签中的内容 ~ attrs:字典,通过键值对的方式获取标签的属性值
-
-
保存数据
-
CSV(逗号分隔值文件) (
csv库
)~ reader / writer ---> writerow() # 写一行 writerows() # 写多行
-
Excel(
xlrd/xlwt(excel2007版本前)
/openpyxl/(2007版本后)
)~ Workbook ---> 工作簿 ---> create_sheet() ---> Worksheet ---> 工作表 ---> cell(row, col, value) ---> 单元格
-
-
-
如何抓取动态内容?
-
直接找到提供JSON数据的接口
- 浏览器开发者工具 ---> Network ---> XHR - 专业的抓包工具 ---> Charles / Fiddler / Wireshark
-
Selenium
驱动浏览器获取动态内容- 自动化测试工具 ~ IDE ~ Remote Control ~ WebDriver:驱动浏览器模拟用户操作 ---> 抓取到动态内容 - Chrome() ~ get():加载页面 ~ 隐式等待 / 显示等待 # 隐式等待 # 在使用find_xxx方法使用页面元素时,如果元素还没有出现 browser.implicitly_wait(10) # 显示等待 # wait = WebDriverException(browser, 10) # wait.until(expected_conditions.presence_of_all_elements_located(By.CSS_SELECTOR, 'span.img>img')) # 进入页面框架中 xpath = browser.find_element_by_xpath(xpath语法) browser.switch_to.frame(xpath) # 进入框架 - implictly_wait(10):如果元素在10秒内没有出现就引发异常 - WebDriverWait(browser, 10) ---> until() ---> 指定等待条件 ~ page_source:页面带动态内容的HTML代码 ~ find_element_by_xxx() ---> WebElement ~ find_elements_by_xxx() ---> [WebElement] - text:获取标签中的文本内容 - get_attribute():获取标签属性
-
-
如何实现并发(并发)编程
并行:真正的同时进行,需要多CPU的支持 并发:可能不是真正的同时进行,但是通过快速的切换制造出并行的效果 线程:操作系统分配CPU的基本单位,最小的执行单元 进程:操作系统分配内存的基本单位,是程序在一组数据上的活动 通常我们启动一个程序,就启动了一个(或多个)进程,一个进程中又可以包含 一个或多个线程。 单线程(只有主线程,只有唯一的一个执行线索) ~ 多线程 ---> I/O密集型任务(爬虫)---> GIL(全局解释器锁)---> 无法使用多核特性 from concurrent.futures.thread import ThreadPoolExecutor # 多线程 池 导入 # 多线程池 语法(ThreadPoolExecutor) with concurrent.futures.ThreadPoolExecutor() as pool: for number in PRIMES: f = pool.submit(需要执行的函数, 参数) n = f.result() # n 为每个 进程的返回值 print(f'{n}') ~ 多进程 ---> 计算密集型任务(音视频编解码、文件压缩、机器学习算法) from concurrent.futures import ProcessPoolExecutor # 多进程 池 导入 # 多进程池 语法(ProcessPoolExecuto) with concurrent.futures.ProcessPoolExecutor() as pool: for number in PRIMES: f = pool.submit(需要执行的函数, 参数) n = f.result() # n 为每个 进程的返回值 print(f'{n}') ~ 异步编程 ---> I/O密集型任务(爬虫)---> 通过提高CPU利用率达到协作式并发 C ---> CPython ---> malloc() / free() Java ---> Jython C# ---> IronPython Python ---> PyPy
-
easyorc
(安装方法:pip install easyocr
) ---- 光学识别文字