Python Selenium+Requests爬虫[双线程]

您所在的位置:网站首页 今日的照片 Python Selenium+Requests爬虫[双线程]

Python Selenium+Requests爬虫[双线程]

2024-07-13 02:41| 来源: 网络整理| 查看: 265

码前冷静分析 首先需要准备好selenium、requests库以及Chromedriver 这个就不细说了,有很多博客可以参考 然后讲一下大体思路 首先搜索想要爬取图片的关键词- 接着是“搜集”搜索结果- 然后想办法逐一进入搜索结果,进而获取内容- 最后就是下载了 框架大体如下

框架是个大体思路(草稿),写代码的时候可以灵活来

def get_list(url): #目的是根据关键词搜索,抓取每一条结果的图片链接 lst = [] browser = webdriver.Chrome() wait = ww(browser, 10) #……等等等等 return lst #胡乱摸索了线程简单的应用,就copy了另一个一样的下载函数 def download_pic1(lst): #逐一遍历列表中的图片链接,下载美图 return '' def download_pic2(lst): #逐一遍历列表中的图片链接,下载美图 return '' def main(): global keyword keyword = '鬼刀' basic_url = 'https://www.toutiao.com/' lst = get_list(basic_url) #访问主页,搜索,收集结果的图片链接,返回列表 download_pic(lst) #根据链接下载图片 #就是这么小白式的简单粗暴,水平还不够,暂时就只弄两个函数吧 #虽然是有点臃肿了,嘤嘤嘤 先声明下,本人是个小白,可能思路,代码存在一些个问题这里还请大家多多指教 完整代码在文末 开 码 首先把要用的库给喊粗来 库,函数的使用介绍有很多超棒的博客,本文会给出部分链接 好的,上代码 import requests from time import sleep import os import os.path as op from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait as ww import threading 1.1 访问今日头条首页,关键词传送及点击搜索 def get_list(basic_url): lst = [] browser = webdriver.Chrome() wait = ww(browser, 10) try: browser.get(basic_url) #找到搜索框节点 input = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#rightModule > div.search-wrapper > div > div > div > input'))) #找到搜索按钮节点 click = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#rightModule > div.search-wrapper > div > div > div > div > button'))) input.send_keys(keyword) #模拟传入搜索词 sleep(2) #输入后停一下,要不然立马让你验证,来自小白的喵喵喵 click.click() #模拟点击搜索按钮 except Exception as er: print(er) # 两个节点的查找看下图 节点查找~超详细解答如下博文

博主 Eastmount 原创 【[python爬虫] Selenium常见元素定位方法和操作的学习介绍】

wait用法详解~如下链接

博主 不码不成才 原创 【python+selenium中的wait事件】

CSS选择器用法介绍~博文链接如下

博主 MXuDong 原创 CSS选择器——cssSelector定位方式详解

到主页后右键—>检查—>开找 - 首先是输入框查找(按照图示顺序很快就找到啦) - 然后右键点击节点,copy—>copy selector

啦啦啦~ 在这里插入图片描述 在这里插入图片描述

接下来同样找到搜索按扭 同样的操作,只是要注意复制对节点信息哦

|在这里插入图片描述

节点查找~超详细解答如下博文

博主 Eastmount 原创 【[python爬虫] Selenium常见元素定位方法和操作的学习介绍】

wait用法详解~如下链接

博主 不码不成才 原创 【python+selenium中的wait事件】

CSS选择器用法介绍~博文链接如下

博主 MXuDong 原创 CSS选择器——cssSelector定位方式详解

这样就进入到了搜索结果界面,接下来就是让它加载出更多结果,通过模拟滑动来实现

1.2 接下来便是模拟滑动页面,出加载更多结果,上码 # 首先把browser切换到当前搜索结果的页面 browser.switch_to.window(browser.window_handles[1]) #滑动多少自己可以任意发挥 for i in range(0, 2001, 250): #下边这个方法来模拟滚动屏幕(详解可以参考其它博客) browser.execute_script(f'window.scrollBy(0, {i})') sleep(2) #滑的差不多了,您是不是该寻思着收集进入结果的''门''了? clicks = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.link.title'))) 模拟滑动所用的方法【execute_script()】相关博客链接如下。

【博主 吾爱乐享 原创-----python学习之滚动页面函数execute_script】 + 【博主 qq_16069927 原创 ----selenium 如何控制滚动条逐步滚动】

来一起找这’'门’‘吧! 在这里插入图片描述 经过观察以及实践,点击标题链接可以进子入页面,就是你了皮卡丘!(就是蓝色阴影那个节点)首先观察,class有两个属性,所以CSS选择器因该是 ‘.link.title’,既然找到了,就都收集起来吧,哈哈 1.3 接下来,就开始邪恶的循环,打开子页面->回到搜索结果页->打开子页面->回到搜索结果页…… 别问为什么,问就是网速慢,先打开页面,让成熟的它自己加载着,然后挨个收割美图链接不要问为什么不找到链接当时就给图片给下了,问就是缺少仪式感。 上码! for clc in clicks[1:10]: # 搜索结果打开数自己定,我是因为穷,惨,所以就10个吧(嘤嘤嘤) clc.click() #进入子页面后,趁它不注意,赶快回到结果页 browser.switch_to.window(browser.window_handles[1]) sleep(4) 1.4 然后开始收割美图链接吧,哈哈! 上码! for num in range(len(browser.window_handles) - 2): #逐个进入子页面 browser.switch_to.window(browser.window_handles[num + 2]) #等待所有图片节点加载粗来,收集它 try: #可能会遇到视频界面,到时候这里判断错误就不管,进入下一个 img = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, 'img[src]'))) except: pass #提取链接到列表 for mg in img: url = mg.get_attribute('src') if url.startswith('http://p') and 'thumb' not in url: lst.append(url) 老问题,找节点,上图!!! 通过分析,可以看出,文章中图片链接都在图中红线标注的 ‘路径’内,所以……在这里插入图片描述 可以构造一个CSS选择器,筛选出所有含图链接节点 ,通过实战,发现有两种页面: 常见的一种是一页到底那种,图片在-> ‘.article-content div .pgc-img img[src]’, 另一种是跟ins一样左右切换那种 两种页面图片节点路径就不一样了,但是标签名都是属性都是’src’,所以选择器就粗糙一点"img[src]" 这样就需要筛选一下了,粗糙的选择器就会获取到一些广告图,实战发现,广告图链接几乎都是’https://……”而图片链接是“http://……”这就很妙了,如代码

【这里很粗糙,还是可能会爬到不相关的,flag:以后有时间再改进改进】

2.接下来就是下载了! 这里我后来翻了一些优秀博客,胡乱摸索,写了个very简单(因为菜)的双线程下载 说白了就是同时运行两个下载函数,男人嘛,不能叫快要叫效率 上码 def download_pic1(): #单独搞个文件夹存一下 path = r'C:\Users\PXO\Desktop\杂\Toutiao_pic\\' + keyword if not op.exists(path): os.mkdir(path) ln = len(lst) id = [i for i in range(ln)] cnt = 1 for url in lst[:ln//2]:#负责前半部分列表下载 #开始搞事情,遍历图片链接,get get get! r = requests.get(url) #这里设置文件保存路径(含文件名) pic_path = path + '\\' + f'{keyword}_pic_{id.pop(0)}.jpg' #以二进制写入方式打开命名好的文件 with open(pic_path, 'wb+') as ff: #写入获取到的图片(二进制)//养成好习惯,随手关闭 ff.write(r.content) ff.close() #下边是一个小优化,刷新显示当前下载状态 op1 = cnt*120//ln en = 60 - op1 opp, enn = '-'*op1, '*'*en print(f'\r[1]下载ing:已下{cnt}/{ln//2}张,[{opp}>{enn}] {(2 * cnt) / len(lst):.1%}', end='') cnt += 1 #下边copy一下就是另一个啦 def download_pic2(): path = r'C:\Users\PXO\Desktop\杂\Toutiao_pic\\' + keyword if not op.exists(path): os.mkdir(path) ln = len(lst) id = [i for i in range(ln)] id.reverse() cnt = 1 for url in lst[ln//2:]:#负责下载后半部分 r = requests.get(url) pic_path = path + '\\' + f'{keyword}_pic_{id.pop(0)}.jpg' with open(pic_path, 'wb+') as ff: ff.write(r.content) ff.close() op1 = cnt*120//ln en = 60 - op1 opp, enn = '-'*op1, '*'*en print(f'\r[2]下载ing:已下{cnt}/{ln//2}张,[{opp}>{enn}] {(2 * cnt) / len(lst):.1%}', end='') cnt += 1 小说明:这里就不传参数了,直接把列表定义为全局变量 线程的代码,还有博客参考如下 #大家可以参考下面给出的优秀博客 threads = [] th1 = threading.Thread(target=download_pic1) threads.append(th1) th2 = threading.Thread(target=download_pic2) threads.append(th2) for th in threads: th.setDaemon(True) th.start() th.join() 参考博客链接 [博主 n_laomomo 原创]----Python多线程threading用法 较详细介绍 【博主 DrStream 原创】----python:threading.Thread类的使用详解 奉上完整代码 注意:爬取的时候会出现超时,然后就over了,除了使用try来’试错‘,还可以适当用一下time库的sleep() import requests from time import sleep import os import os.path as op from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait as ww import threading def get_list(basic_url): ''' #这里是无界面浏览器相关操作,不想要弹出界面的话, #把下边那行换成这些就ok browser_options = webdriver.ChromeOptions() browser_options.add_argument('--headless') browser = webdriver.Chrome(options=browser_options) ''' browser = webdriver.Chrome() #这行就是那行(手动滑稽) wait = ww(browser, 20) try: browser.get(basic_url) print('访问成功!!') sleep(1) input = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#rightModule > div.search-wrapper > div > div > div > input'))) click = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#rightModule > div.search-wrapper > div > div > div > div > button'))) input.send_keys(keyword) sleep(2) click.click() sleep(1) print('搜索成功!') browser.switch_to.window(browser.window_handles[1]) for i in range(0, 2001, 250): browser.execute_script(f'window.scrollBy(0, {i})') print(f'\r加载中。。。{i/2000:.1%}', end='') sleep(3) print('') clicks = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.link.title'))) cnt = 0 want = 10 ## 爬取页面数 for clc in clicks[: want]: clc.click() sleep(2) cnt += 1 browser.switch_to.window(browser.window_handles[1]) print(f'\r已打开{cnt}个界面,比例{cnt/want:.2%}', end='') print() for num in range(want): browser.switch_to.window(browser.window_handles[num + 2]) try: img = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, 'img[src]'))) #.article-content div .pgc-img img[src] except: pass for mg in img: url = mg.get_attribute('src') if url.startswith('http://p'): lst.append(url) except Exception as t: print(t) def download_pic1(): path = r'C:\Users\PXO\Desktop\杂\Toutiao_pic\\' + keyword if not op.exists(path): os.mkdir(path) ln = len(lst) id = [i for i in range(ln)] cnt = 1 for url in lst[:ln//2]: r = requests.get(url) pic_path = path + '\\' + f'{keyword}_pic_{id.pop(0)}.jpg' with open(pic_path, 'wb+') as ff: ff.write(r.content) ff.close() op1 = cnt*120//ln en = 60 - op1 opp, enn = '-'*op1, '*'*en print(f'\r[1]下载ing:已下{cnt}/{ln//2}张,[{opp}>{enn}] {(2 * cnt) / len(lst):.1%}', end='') cnt += 1 def download_pic2(): path = r'C:\Users\PXO\Desktop\杂\Toutiao_pic\\' + keyword if not op.exists(path): os.mkdir(path) ln = len(lst) id = [i for i in range(ln)] id.reverse() cnt = 1 for url in lst[ln//2:]: r = requests.get(url) pic_path=path+'\\'+f'{keyword}_pic_{id.pop(0)}.jpg' with open(pic_path, 'wb+') as ff: ff.write(r.content) ff.close() op1 = cnt*120//ln en = 60 - op1 opp, enn = '-'*op1, '*'*en print(f'\r[2]下载ing:已下{cnt}/{ln//2}张,[{opp}>{enn}] {(2 * cnt) / len(lst):.1%}', end='') cnt += 1 def main(): global keyword, lst lst = [] keyword = '鬼刀' basic_url = 'https://www.toutiao.com/' get_list(basic_url) threads = [] th1=threading.Thread(target=download_pic1) threads.append(th1) th2=threading.Thread(target=download_pic2) threads.append(th2) for th in threads: th.setDaemon(True) th.start() th.join() main()

在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3