当前位置: 首页 > news >正文

扬州网站建设费用wordpress 图片 cdn

扬州网站建设费用,wordpress 图片 cdn,网络公关事件,ui培训机构排名除了运行 Appium 的基本条件外#xff0c;还要一个日志输出库 安装#xff1a; pip install loguru 思路分析 首先我们观察一下整个 app5 的交互流程#xff0c;其首页分条显示了电影数据#xff0c; 每个电影条目都包括封面#xff0c;标题#xff0c; 类别和评分 4…除了运行 Appium 的基本条件外还要一个日志输出库 安装  pip install loguru 思路分析 首先我们观察一下整个 app5 的交互流程其首页分条显示了电影数据 每个电影条目都包括封面标题 类别和评分 4 个内容 点击一个电影条目 就可以看到这个电影的详细介绍包括标题类别上映时间评分时长电影简介等内容 可见详情页远比首页内容丰富 我们需要依次点击每个电影条目抓取看到的所有内容把所有电影条目的信息都抓取下来后回退到首页 另外首页一开始只显示 10 个电影条目需要上拉才能显示更多数据一共 100 条数据所以为了爬取所有数据我们需要在适当的时候模拟手机上拉的操作已加载更多的数据 综上这里总结出基本爬取流程 遍历现有的电影条目依次模拟点击每个电影条目进入详情页 爬取详情页的数据爬取完毕后模拟点击回退按钮的操作返回首页 当首页的所有电影条目即将爬取完毕时模拟上拉操作加载更多数据 在爬取过程中将已经爬取的数据记录下来以免重复爬取 100 条数据爬取完毕后终止爬取 基本实现 在编写代码的过程中我们用 Appium 观察现有的  App 的源代码以便编写节点的提取规则。 首先启动 Appium 服务然后启动 Session 打开电脑端的调试窗口 首先观察一些首页各个电影条目对应的 UI 树是怎样的。 通过观察可以发现每个电影条目都是一个 android.widget.LinearLayout 节点 该节点带有一个属性 resoutce-id 为 com.goldze.mvvmhabit:id/item 条目内部的标题是一个 android.widget.TextView 节点该节点带有一个属性 resource-id , 属性值是 com.goldze.mvvmhabit:id/tv_title, 我们可以选中所有的电影条目节点同时记录电影标题去重 去重的目的 因为对已经被渲染出来但是没有呈现在屏幕上的节点我们是无法获取其信息的。在不断上拉爬取的过程中我们同一时刻只能获取屏幕中能看到的所有电影条目的节点被滑动出屏幕外的节点已经获取不到了。所有需要记录一下已经爬取的电影条目节点以便下次滑动完毕后可以接着上一次爬取。由于此案例中的电影标题不存在重复因此我们就用它来实现记录和去重 接下来做一些初始化声明 from appium import webdriver from appium.options.android import UiAutomator2Options from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait from selenium.common.exceptions import NoSuchElementExceptionSERVER http://localhost:4723/wd/hub DESIRED_CAPABILITIES {platformName: Android,deviceName: LIO_AN00,appPackage: com.goldze.mvvmhabit,appActivity: .ui.MainActivity,noReset: True } PACKAGE_NAME DESIRED_CAPABILITIES[appPackage] TOTAL_NUMBER 100 这里我们首先声明了 SERVER 变量 即 Appium 在本地启动的服务地址。 接着声明了 DESITED_CAPABILITIES 这就是 Appium 启动示例 App 的配置参数其中 deviceName 需要更改成自己手机的 model 名称 可以使用 adb devices –l  通过 cmd 获取。另外这里额外声明了一个变量 PACKAGE_NAME 即包名 这是为后续编写获取节点的逻辑准备的。 最后声明 TOTAL_NUMBER 为 100 代表电影条目的总数为 100 之后以此为判断终止爬取 接下来我么声明 driver 对象 并初始化一些必要的对象和变量 driver webdriver.Remote(SERVER, optionsUiAutomator2Options().load_capabilities(DESIRED_CAPABILITIES)) wait WebDriverWait(driver, 30) window_size driver.get_window_size() window_width, window_height window_size.get(width), window_size.get(height) 这里的 wait 变量就是一个 WebDriverWait 对象 调用它的 until 方法可以实现如果查找到目标接节点就立即返回如果等待 30 秒还查找不到目标节点就抛出异常。 我们还声明了 window_width, window_height 变量 分别代表屏幕的宽高 初始化工作完成下面爬取首页的所有电影条目 def scrape_index():items wait.until(EC.presence_of_all_elements_located((By.XPATH, f//android.widget.LinearLayout[resource-id{PACKAGE_NAME}:id/item])))return items 这里实现了一个 scrape_index 方法 使用 XPath 选择对应的节点 开头的 // 代表匹配根节点的所有子孙节点即所有符合后面条件的节点都会被筛选出来 这里对节点名称 android.widget.LinearLayout 和 属性 resource-id 进行了组合匹配。 在外层调用了 wait 变量的 until 方法最后的结果就是如果符合条件的节点加载出来看 就立即把这个节点赋值为 items 变量并返回 items 否则抛出超时异常 所以在正常情况下使用 scrape_index 方法可以获得首页上呈现的所有电影条目数据 接下来就可以定义一个 main 方法来调用 scrape_index 方法了  from loguru import logger def main():elements scrape_index()for element in elements:element_data scrape_detail(element)logger.debug(fscraped data {element_data})if __name__ __main__:main() 这里在 main 方法中首先调用 scrape_index 方法提取了当前首页的所有节点然后遍历这些节点并想通过一个 scrape_detail 方法提取每部电影的详情信息最后返回并输出日志 那么问题明确了scrape_detail 方法如何实现大致思考一下可以想到该方法需要做到如下三件事 模拟点击 element , 即首页的电影条目节点 进入详情页后爬取电影信息 点击回退按钮后返回首页 所以这个方法实现为 def scrape_detail(element):logger.debug(fscraping {element})element.click()wait.until(EC.presence_of_element_located((By.ID, f{PACKAGE_NAME}:id/detail)))title wait.until(EC.presence_of_element_located((By.ID, f{PACKAGE_NAME}:id/title))).get_attribute(text)categories wait.until(EC.presence_of_element_located((By.ID, f{PACKAGE_NAME}:id/categories_value))).get_attribute(text)score wait.until(EC.presence_of_element_located((By.ID, f{PACKAGE_NAME}:id/score_value))).get_attribute(text)minute wait.until(EC.presence_of_element_located((By.ID, f{PACKAGE_NAME}:id/minute_value))).get_attribute(text)published_at wait.until(EC.presence_of_element_located((By.ID, f{PACKAGE_NAME}:id/published_at_value))).get_attribute(text)drama wait.until(EC.presence_of_element_located((By.ID, f{PACKAGE_NAME}:id/drama_value))).get_attribute(text)driver.back()return {title: title,categories: categories,score: score,minute: minute,published_at: published_at,drama: drama } 实现该方法需要先弄清楚详情页每个及诶蒂娜对应的节点名称 属性都是怎样的于是再次打开调试窗口点击一个电影标题进入详情页 查看器 DOM 树 可以观察到整个详情页对应一个 android.widget.ScrollView 节点其包含的 resource-id 属性值为 com.goldze.mnnmhabit:id/detail 。详情页上的标题类别评分时长上映时间剧情简介页都有各自的节点名称和 resource-id , 这里就不展开描述了 从 Appium 的 Source 面板即可查看 在 scrape_detail 方法中首先调用了 element 的click 方法进入对应的详情页然后等待整个详情页的信息即 com.goldze.mnnmhabit:id/detail 加载出来之后顺次爬取了标题类别评分时长上映时间剧情简介爬取完毕后抹蜜点击回退按钮最后将所有爬取的内容构成一个字典返回 其实现在我们已经可以成功获取首页最开始加载的几条电影信息了执行一下代码 部分输出内容 2024-08-16 16:05:22.177 | DEBUG    | __main__:scrape_detail:32 - scraping appium.webdriver.webelement.WebElement (sessionc9f0c1dc-d98a-45bc-b65f-60c5b3831219, element00000000-0000-0015-7fff-ffff00000011) 2024-08-16 16:05:24.149 | DEBUG    | __main__:main:62 - scraped data {title: 霸王别姬, categories: 剧情、爱情, score: 9.5, minute: 171分钟, published_at: 1993-07-26, drama: 影片借一出《霸王别姬》的京戏牵扯出三个人之间一段随时代风云变幻的爱恨情仇。段小楼张丰毅 饰与程蝶衣张国荣 饰是一对打小一起长大的师兄弟两人一个演生一个饰旦一向配合天衣无缝尤其一出《霸王别姬》更是誉满京城为此两人约定合演一辈子《霸王别姬》。但两人对戏剧与人生关系的理解有本质不同段小楼深知戏非人生程蝶衣则是人戏不分。段小楼在认为该成家立业之时迎娶了名妓菊仙巩俐 饰致使程蝶衣认定菊仙是可耻的第三者使段小楼做了叛徒自此三人围绕一出《霸王别姬》生出的爱恨情仇战开始随着时代风云的变迁不断升级终酿成悲剧。} 上拉加载更多内容 现在在上面代码的基础上加入上拉加载更多数据的逻辑因此需要判断什么时候上拉加载数据。想想我们平时在浏览器浏览数据的时候是怎么操作的 一般是在即将看完的时候上拉那这里页一样可以让程序在遍历到位于偏下方的电影条目的时候开始上拉。例如当爬取的节点对应的电影条目差不多位于页面高度的 80% 时就触发上拉加载将 main 方法改写如下 def main():elements scrape_index()for element in elements:element_location element.locationelement_y element_location.get(y)if element_y / window_height 0.5:logger.debug(fscroll up)scroll_up()element_data scrape_detail(element)logger.debug(fscraped data {element_data}) 这里遍历是判断了  element 的位置获取了其 y 的坐标值当该值小于页面高度的 80% 时触发上拉加载加载的方法是 scroll_up 其定义如下 def scroll_up():driver.swipe(window_width * 0.5, window_height * 0.8, window_width * 0.5, window_height * 0.5, 1000) 方法 driver.swipe(start_x, start_y, end_x, end_y, 时间 start_x, start_y 开始上拉的 横纵坐标 end_x, end_y上拉到的位置的横纵坐标 时间上拉用时多久 去重终止和保存数据 在本节开始部分我们曾提到需要额外添加根据标题进行去重和判断终止的逻辑所以在遍历首页中每个电影条目的时候还需要提取一下标题然后将其存入一个全局变量中 def get_element_title(element):try:element_title element.find_element(byBy.ID, valuef{PACKAGE_NAME}:id/tv_title).get_aribute(text)return element_titleexcept NoSuchElementException:return None 这里定义了一个 get_element_title 方法该方法接收一个 element 参数 即首页电影条目对应的节点对象然后提取其标题文本并返回最后将 main 方法修改如下 scraped_titles [] def main():while len(scraped_titles) TOTAL_NUMBER:elements scrape_index()for element in elements:element_title get_element_title(element)if not element_title or element_title in scraped_titles:continueelement_location element.locationelement_y element_location.get(y)if element_y / window_height 0.5:logger.debug(fscroll up)scroll_up()element_data scrape_detail(element)scraped_titles.append(element_title)logger.debug(fscraped data {element_data}) 这里在 main 方法里添加了 while 循环 入股哦爬取的电影条目数量尚未达到数量 TOTAL_NUMBER, 就接着爬取 直到爬取完毕。 其中就调用 get_element_title 方法提取了电影标题然后将已经爬取的电仪标题存储在全局变量 scraped_titles 中 如果经判断 当前节点对应的电影已经爬取过了 就跳过 否则接着爬取爬取完毕后将标题存到 scraped_titles 变量里这样就实现了去重 保存数据 最后可以再添加一个保存数据的逻辑将爬取的数据保存到本地 movie 文件夹中 数据以 JSON 形式保存代码如下 import os import jsonOUTPUT_FOLDER movie os.path.exists(OUTPUT_FOLDER) or os.makedirs(OUTPUT_FOLDER)def save_date(element_data):with open(f{OUTPUT_FOLDER}/{element_data.get(title)}.json, w, encodingutf-8) as f:f.write(json.dumps(element_data, ensure_asciiFalse, indent2))logger.debug(fsaved as file {element_data.get(title)}.json) 最后在 main 方法中添加调用逻辑即可 完整代码 from appium import webdriver from appium.options.android import UiAutomator2Options from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait from selenium.common.exceptions import NoSuchElementException from loguru import logger import os import jsonSERVER http://localhost:4723/wd/hub DESIRED_CAPABILITIES {platformName: Android,deviceName: LIO_AN00,appPackage: com.goldze.mvvmhabit,appActivity: .ui.MainActivity,noReset: True } OUTPUT_FOLDER movie os.path.exists(OUTPUT_FOLDER) or os.makedirs(OUTPUT_FOLDER) PACKAGE_NAME DESIRED_CAPABILITIES[appPackage] TOTAL_NUMBER 100scraped_titles [] driver webdriver.Remote(SERVER, optionsUiAutomator2Options().load_capabilities(DESIRED_CAPABILITIES)) wait WebDriverWait(driver, 30) window_size driver.get_window_size() window_width, window_height window_size.get(width), window_size.get(height)def scrape_index():items wait.until(EC.presence_of_all_elements_located((By.XPATH, f//android.widget.LinearLayout[resource-id{PACKAGE_NAME}:id/item])))return itemsdef scrape_detail(element):logger.debug(fscraping {element})element.click()wait.until(EC.presence_of_element_located((By.ID, f{PACKAGE_NAME}:id/detail)))title wait.until(EC.presence_of_element_located((By.ID, f{PACKAGE_NAME}:id/title))).get_attribute(text)categories wait.until(EC.presence_of_element_located((By.ID, f{PACKAGE_NAME}:id/categories_value))).get_attribute(text)score wait.until(EC.presence_of_element_located((By.ID, f{PACKAGE_NAME}:id/score_value))).get_attribute(text)minute wait.until(EC.presence_of_element_located((By.ID, f{PACKAGE_NAME}:id/minute_value))).get_attribute(text)published_at wait.until(EC.presence_of_element_located((By.ID, f{PACKAGE_NAME}:id/published_at_value))).get_attribute(text)drama wait.until(EC.presence_of_element_located((By.ID, f{PACKAGE_NAME}:id/drama_value))).get_attribute(text)driver.back()return {title: title,categories: categories,score: score,minute: minute,published_at: published_at,drama: drama}def scroll_up():print(window_height)print(window_height * 0.8)print(window_height * 0.5)driver.swipe(window_width * 0.5, window_height * 0.8, window_width * 0.5, window_height * 0.5, 1000)def get_element_title(element):try:element_title element.find_element(byBy.ID, valuef{PACKAGE_NAME}:id/tv_title).get_attribute(text)return element_titleexcept NoSuchElementException:return Nonedef save_date(element_data):with open(f{OUTPUT_FOLDER}/{element_data.get(title)}.json, w, encodingutf-8) as f:f.write(json.dumps(element_data, ensure_asciiFalse, indent2))logger.debug(fsaved as file {element_data.get(title)}.json)def main():while len(scraped_titles) TOTAL_NUMBER:elements scrape_index()for element in elements:element_title get_element_title(element)if not element_title or element_title in scraped_titles:continueelement_location element.locationelement_y element_location.get(y)if element_y / window_height 0.5:logger.debug(fscroll up)scroll_up()element_data scrape_detail(element)scraped_titles.append(element_title)save_date((element_data))logger.debug(fscraped data {element_data})if __name__ __main__:main()
http://www.dnsts.com.cn/news/75616.html

相关文章:

  • 做网站 百度推广linux软件开发工具
  • vps正常网站打不开wordpress 后台502
  • 启铭网站建设聊城做手机网站
  • 做网站和彩票的同步开奖怎么做株洲正规竞价优化推荐
  • 国际物流网站制作模板如何建立网站服务器
  • 模板网站建设方案北京外包做网站如何报价
  • 网站建设需要什么硬件和软件有哪些方面桂林
  • 深圳门户网站开发网站建设实训致谢语
  • 企业做个网站多少钱网站备案期间停止解析
  • 网站建设备案条件seo快速排名培训
  • 免费流程图网站做外贸网站注意什么
  • 做中学网站网站开发岗位之间的关联
  • 一个网站的作用是什么宁波seo网站建设费用
  • 东莞没有网站的公司私域流量运营平台有哪些
  • 用别人公司名字做网站违法么公共数据开放网站建设
  • 指定网站长期建设 运营计划wordpress安装完无法登录
  • 电子商务网站建设 考卷外贸商城网站建设
  • 什么是建设网站工具建一个公司网站要多少钱
  • 网站产品页如何做优化陕西省城乡建设学校网站
  • 上海徐汇网站建设公司开发公司融资专干笔试
  • 可以写代码的网站产品代理平台
  • 龙岗网站建设哪家好网页图片设置
  • 专注网站建设与优化辽宁平台网站建设平台
  • 毕业设计做系统网站好成都百度推广开户公司
  • 如何建立竞价网站网站开发 产品经理
  • 网站开发背景图模板wordpress admin_init
  • 西安阎良区建设局网站国家住房与城乡建设部网站首页
  • 德阳网站开发熊掌号网站建设报价方案doc
  • 厦门地税网站建设平台类网站有哪些
  • 给小学生做家教的网站广州公司注册官网