摘要:本篇文章探讨了大数据采集之python的docker爬虫技术- 多设备端并发抓取抖音粉丝数据(22),希望阅读本篇文章以后大家有所收获,帮助大家对相关内容的理解更加深入。
本篇文章探讨了大数据采集之python的docker爬虫技术- 多设备端并发抓取抖音粉丝数据(22),希望阅读本篇文章以后大家有所收获,帮助大家对相关内容的理解更加深入。
1.桌面有夜神模拟器多开
2.选择中,点击复制,可能一下复制出来3个,咱们不需要那么多删除2个就可以了,你如果电脑足够强大也可以复制多个,下面代码的思路是一样的。
3.复制完成后,改下别名,方便区别
启动2个模拟器。
按照常理一般的互联网操作,如果要实现多任务抓取基本都是使用容器化的来完成的,但是目前直接说docker有点尚早,不过这个系列肯定是要实现docker的多设备抓取的,这里先说说使用python多进程的方式来完成。
1.查看夜神模拟器的端口,启动cmd,输入
adb devices
2.如果输入adb devices没有列表
在启动夜神模拟器的时候adb还没启动。也就是夜神模拟器比adb先启动,解决方案。
1.打开任务管理器,查看夜神模拟器的PID,可以通过点击状态-选中PID
2.刚查看到的PID
netstat -ano | findstr ""452""
netstat -ano | findstr ""16712""
3.夜神模拟器端口是有规律的,第一个模拟器端口是62001,第二个是62025,第三个62025+1,第4个62025+2
手动的命令方式连接设备
adb connect 127.0.0.1:62025
5.appium【客户端】需要设置udid,在appium里面识别就是udid,因为之前是一台设备所以不需要指定udid,光指定deviceName就可以了。
appium【服务端】需要设置bootstrapPort,服务端进行设置,设备和appium通信的端口。
7.appium的2台的属性设置
1.douyin1 port=4723 bootstrapPort=4724
2.douyin1 port=4725 bootstrapPort=4726
报错解决方案
selenium.common.exceptions.WebDriverException: Message: An unknown server-side error occurred while processing the command. Original error: Failed to Dump Window Hierarchy
解决方案
在含有Emoji特殊符号的页面中,爆出Failed to Dump Window Hierarchy
won’t be solved until the new android driver is completed. This is a known bug in uiautomator v1
此问题是uiautomator自身bug,换用Android5.1以上的系统
#!/usr/bin/env python import time from appium import webdriver from selenium.webdriver.support.ui import WebDriverWait import multiprocessing def get_size(driver): x = driver.get_window_size()['width'] y = driver.get_window_size()['height'] return (x, y) def handle_douyin(driver): while True: #定位搜索框 if WebDriverWait(driver,60).until(lambda x:x.find_element_by_xpath(""//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[2]/android.widget.EditText[1]"")): #获取douyin_id进行搜索 driver.find_element_by_xpath(""//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[2]/android.widget.EditText[1]"").send_keys('1860719705') while driver.find_element_by_xpath(""//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[2]/android.widget.EditText[1]"").text != '1860719705': driver.find_element_by_xpath(""//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[2]/android.widget.EditText[1]"").send_keys('1860719705') time.sleep(0.1) #点击搜索 driver.find_element_by_xpath(""//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.widget.TextView[1]"").click() #点击用户标签 if WebDriverWait(driver,30).until(lambda x:x.find_element_by_xpath(""//android.widget.TextView[@text='用户']"")): driver.find_element_by_xpath(""//android.widget.TextView[@text='用户']"").click() #点击头像 if WebDriverWait(driver,30).until(lambda x:x.find_element_by_xpath(""//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.support.v4.view.ViewPager[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[2]/android.view.View[1]/android.support.v7.widget.RecyclerView[1]/android.widget.RelativeLayout[1]/android.widget.RelativeLayout[1]/android.widget.ImageView[1]"")): driver.find_element_by_xpath(""//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.support.v4.view.ViewPager[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[2]/android.view.View[1]/android.support.v7.widget.RecyclerView[1]/android.widget.RelativeLayout[1]/android.widget.RelativeLayout[1]/android.widget.ImageView[1]"").click() #点击粉丝按钮 if WebDriverWait(driver,30).until(lambda x:x.find_element_by_xpath(""//android.widget.TextView[@text='粉丝']"")): driver.find_element_by_xpath(""//android.widget.TextView[@text='粉丝']"").click() x1 = int(driver.get_window_size()['width']*0.5) y1 = int(driver.get_window_size()['height']*0.75) y2 = int(driver.get_window_size()['height']*0.25) while True: time.sleep(3) if '没有更多了' in driver.page_source: break elif 'TA还没有粉丝' in driver.page_source: break else: driver.swipe(x1,y1,x1,y2) time.sleep(0.5) #返回 driver.find_element_by_xpath(""//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.widget.RelativeLayout[1]/android.widget.FrameLayout[1]/android.widget.ImageView[1]"").click() #返回 driver.find_element_by_id(""com.ss.android.ugc.aweme:id/jk"").click() #重新清空用户id driver.find_element_by_xpath(""//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[2]/android.widget.EditText[1]"").clear() def handle_appium(device,port): cap = { ""platformName"": ""Android"", ""platformVersion"": ""4.4.2"", ""deviceName"": device, ""udid"":device, # 真机的 # ""platformName"": ""Android"", # ""platformVersion"": ""7.1.2"", # ""deviceName"": ""10d4e4387d74"", ""appPackage"": ""com.ss.android.ugc.aweme"", ""appActivity"": ""com.ss.android.ugc.aweme.main.MainActivity"", ""noReset"": True, ""unicodeKeyboard"": True, ""resetkeyboard"": True } driver = webdriver.Remote(""//localhost:""+str(port)+""/wd/hub"", cap) try: # 点击搜索 print('点击搜索') if WebDriverWait(driver, 60).until(lambda x: x.find_element_by_xpath( ""//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.support.v4.view.ViewPager[1]/android.widget.FrameLayout[1]/android.support.v4.view.ViewPager[1]/android.widget.TabHost[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.view.View[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[2]/android.widget.FrameLayout[1]/android.widget.ImageView[1]"")): driver.find_element_by_xpath( ""//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.support.v4.view.ViewPager[1]/android.widget.FrameLayout[1]/android.support.v4.view.ViewPager[1]/android.widget.TabHost[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.view.View[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[2]/android.widget.FrameLayout[1]/android.widget.ImageView[1]"").click() except: # [26,76][115,165] driver.tap([(26, 76), (115, 165)], 500) handle_douyin(driver) if __name__ == '__main__': m_list = [] #定义了2台虚拟设备,夜神模拟器 devices_list = [""127.0.0.1:62001"",""127.0.0.1:62025""] for device in range(len(devices_list)): port = 4723 + 2 * device m_list.append(multiprocessing.Process(target=handle_appium,args=(devices_list[device],port,))) for m1 in m_list: m1.start() for m2 in m_list: m2.join()
1.启动2个appium
之前上边已经提到过的端口(4723 4724 )(4725 4726)
2.启动python代码,查看效果
调试测试代码次数太多了,douyin要求我登录,哈哈
刚出现的因为访问册数太多,douyin那边识别了,这样需要解决。通过代理的方式。
1.购买代理的ip,还是用咱们的老朋友【阿布云】https://www.abuyun.com/
2.登录【阿布云】后,使用mitmdump的方式,设置阿布云的代理
启动cmd,输入
mitmdump -s test.py -p 8889 --mode upstream:HTTP隧道服务器:端口 --upstream-auth 通行证书:通行秘钥
mitmdump -s test.py -p 8889 --mode upstream://http-pro.abuyun.com:9010 --upstream-auth HS821YO6BA7D6M8P:75021E5CF3AB82EE
3.模拟器的wifi也要设置对应的代理,之前说过在重复说下。
4.这样就使用了代理的方式了。 所有请求就是代理的阿布云了。
感谢老铁的建议,以后的所有的系列的源码都是按照对应文章进行整理,原来的源码都是按照我的开发历程的,这样不适合中间参与进来的老铁。
PS:调试过程中,夜神模拟器,appium,python代码插件没有问题的话,程序在运行过程中出现的最多的问题还是xpath定位的问题,对于python的代码其实也是很好理解的。另外注意的文章中提到的要使用安卓5.1以上否则会因为页面中含有Emoji特殊符号,爆出Failed to Dump Window Hierarchy。udid对于启动多个模拟器的时候一定要进行设置。
" 本文由职坐标整理发布,学习更多的相关知识,请关注职坐标IT知识库!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号