基础知识 爬虫(spider),是指向网站/网络发起请求,获取、分析并提取有用信息的程序。
爬虫架构 Python 爬虫架构主要由五个部分组成,分别是调度器、URL管理器、网页下载器、网页解析器、应用程序。
调度器:调度url下载器,网页下载器,网页解析器之间的工作。
url管理器: url队列管理,设置爬取顺序权重,防止重复爬取和循环爬取,将需要使用的url传递给网页下载器。
网页下载器: 自动获取网页内容,下载产出HTML文件传递给网页解析器。
网页解析器: 从HTML中提取数据并存储,提取新的url补充至url管理器。
应用程序:由提取出的有用数据组成的应用。
http协议–请求与响应 request:用户将信息通过浏览器发送给服务器。
response:服务器接收并分析请求,返回数据。
爬虫需要一定的http基础,请自行搜索。
可参考Python爬虫详解(一看就懂)-CSDN博客
vscode环境搭建 下载扩展pip manager:便于pip安装管理扩展。下文的扩展请自行搜索下载。
网页下载器requests request
response
简单操作 1 2 3 4 5 6 7 8 import requestsurl = 'https://luvmand.top/' r = requests.get(url) print (r.status_code) print (r.headers) print (r.encoding)
URL管理器 通过设置url管理器实现urls的管理和存储
url管理器的基本代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class url_manager : def __init__ (self ): self.new_urls = set () self.old_urls = set () def add_new_url (self, urls ): if urls is None or len (urls) == 0 : return for url in urls: if url in self.new_urls or url in self.old_urls: continue self.new_urls.add(url) def get_url (self ): if self.if_has_new_url(): url = self.new_urls.pop() self.old_urls.add(url) return url def if_has_new_url (self ): return len (self.new_urls) > 0
网页解析器Beautiful Soup 通过第三方库beautiful soup
从html中提取数据
beautiful soup讲解:Python爬虫:史上最详细的BeautifulSoup教程 - 简书 (jianshu.com)
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import requestsfrom bs4 import BeautifulSoupurl = 'https://luvmand.top/' r = requests.get(url) text = r.text soup = BeautifulSoup(text,'html.parser' ) content = soup.find_all('div' ,class_='content' ) for t in content: if t.string is not None : print (t.string,'\n' ,'/' *30 ,'\n' )
可将本人博客首页的内容打印出。
内容查找:正则表达式与xpath 正则表达式匹配内容 正则表达式入门:正则表达式 – 语法 | 菜鸟教程 (runoob.com)
通过正则表达式可以更方便地匹配内容
python通过import re
来使用正则表达式.
1 2 3 4 5 6 7 8 9 import reurls = soup.find_all('a' ) pattern = r'^/\d+/\d+/\d+/[\s\S]+$' for url in urls: web = re.match (pattern,url['href' ]) if web is not None and url.string is not None : print (url.string,'https://luvmand.top' +web.group())
xpath xpath可以更加便捷地提取源码中的信息。
xpath教学:Python爬虫实战之xpath解析_python xpath-CSDN博客
网页自动化Selenium 很多网站重要数据采用动态加载,单凭Beautiful Soup无法得到数据。通过selenium可直接模拟浏览器对象,便于查找动态元素 。
使用前需要配置虚拟浏览器环境
查阅selenium教学:selenium入门超详细教程——网页自动化操作-CSDN博客
通过selenium的元素查找主要依赖webdriver.find_element()
:
简单示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 from selenium import webdriverfrom selenium.webdriver.common.by import Bybrowser = webdriver.Chrome() browser.get(r'https://luvmand.top/' ) elements = browser.find_elements(By.CLASS_NAME,'content' ) for element in elements: print (element.text,'\n' ) browser.close()
通过get_attribute()
可以得到元素的信息,如abc_url = browser.find_element(By.ID,'abc').get_attribute('src')
实例:爬取动漫网站视频 在此例中,动漫网站 的视频链接为动态元素,且依赖DPlayer加载ts视频,不能直接通过m3u8链接进行下载,需要通过第一个m3u8链接得到第二个链接。
选中视频元素,得到以下代码:
代码中的src
可以通过浏览器直接访问得到可观看的视频,但无法进行下载;
裁剪&url=
后的代码可以得到ffmpy3下载链接。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 import reimport requestsfrom bs4 import BeautifulSoupfrom selenium import webdriverfrom selenium.webdriver.common.by import Byfrom urllib import parseimport managerimport ffmpy3 root_url = 'https://iyhdmw.com/' list_number = input ('输入番剧在网址上的代码(例如https://www.iyhdmw.com/showp/12089.html 为12089)\n' ) video_list_menu_url = root_url+'showp/' +list_number+'.html' if len (list_number) == 0 : print ('未输入代码,程序结束' ) quit() print ('爬取番剧地址为' +video_list_menu_url)response = requests.get(video_list_menu_url) if response.status_code != 200 : raise print ('动漫主页面访问失败' ) quit() else : print ('访问成功' ) index_html = response.text soup = BeautifulSoup(index_html,'html.parser' ) print (soup.title.text)player_choose = soup.findAll('div' ,class_='movurl' )[1 ] episode_list = player_choose.findAll('li' ) episode_number = len (episode_list) print (f'共{episode_number} 集' )manager = manager.url_manager() for episode in episode_list: episode_url = episode.find('a' ) manager.add_new_url({root_url+episode_url.get('href' )}) list_urls = open (f'./file/sakura/list_urls_{soup.title.text} .txt' ,'w' ,encoding='utf-8' ) while (manager.if_has_new_url()): url = manager.get_url() browser = webdriver.Chrome() browser.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument" , { "source" : """ Object.defineProperty(navigator, 'webdriver', { get: () => undefined }) """ }) browser.get(url) browser.implicitly_wait(10 ) video_browser_url = browser.find_element(By.ID,'yh_playfram' ).get_attribute('src' ) list_urls.write(f'{browser.title} : 浏览器观看: ' +video_browser_url) video_url_cutted = re.split(r'&url=' ,video_browser_url) video_currect = parse.unquote(video_url_cutted[1 ]) print (video_currect) list_urls.write(' ffmpeg下载连接: ' +video_currect+'\n' ) list_urls.close()
程序执行完成后,可成功得到含m3u8链接的txt文件:
防止被识别为爬虫代码参考自:selenium webdriver 开启网页失败,被发现为爬虫,的解决办法_driver.execute_cdp_cmd(“page.addscripttoevaluateon-CSDN博客