CategoryResourceRepost/极客时间专栏/数据分析实战45讲/第三模块:数据分析实战篇/37丨数据采集实战:如何自动化运营微博?.md
louzefeng d3828a7aee mod
2024-07-11 05:50:32 +00:00

203 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<audio id="audio" title="37丨数据采集实战如何自动化运营微博" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/78/aa/7828b7dee7210e9a89ab6cabb8a2bbaa.mp3"></audio>
今天我来带你做一个数据采集的实战。之前我讲到可以使用第三方工具比如八爪鱼做数据采集也可以自己编写脚本比如使用Python。编写Python做数据采集和自动化最大的好处就是可控性强每个步骤都可以调试而且可以找到问题所在并一一突破。
今天我就带你使用Python自动化运营微博。关于今天的学习希望你能达成以下的3个学习目标
<li>
掌握Selenium自动化测试工具以及元素定位的方法
</li>
<li>
学会编写微博自动化功能模块:加关注,写评论,发微博;
</li>
<li>
对微博自动化做自我总结。
</li>
## Selenium自动化测试工具
当我们做Web自动化测试的时候可以选用Selenium或者Puppeteer工具。我在[第10篇](https://time.geekbang.org/column/article/76001)的时候简单介绍过Selenium这个工具你可以再回顾一下。Puppeteer通过控制无头Chrome来完成浏览器的工作。这两个工具之间的区别在于Selenium更关注程序执行的流程本身比如找到指定的元素设置相应的值然后点击操作。而Puppeteer是浏览者的视角比如光标移动到某个元素上键盘输入某个内容等。
今天我们继续使用Selenium工具自动化模拟浏览器重点是学习对元素的定位。在第10篇讲到Selenium WebDriver的使用时重点是对HTML进行获取和解析然后通过HTML中的XPath进行提取读取相应的内容。
在今天的实战里我们需要在微博上自动登录加关注发评论发微博等这些操作都需要在浏览器上完成所以我们可以使用Webdriver自带的元素定位功能。
如果我们想定位一个元素可以通过id、name、class、tag、链接上的全部文本、链接上的部分文本、XPath或者CSS进行定位在Selenium Webdriver中也提供了这8种方法方便我们定位元素。
<li>
通过id定位我们可以使用find_element_by_id()函数。比如我们想定位id=loginName的元素就可以使用browser.find_element_by_id(“loginName”)。
</li>
<li>
通过name定位我们可以使用find_element_by_name()函数比如我们想要对name=key_word的元素进行定位就可以使用browser.find_element_by_name(“key_word”)。
</li>
<li>
通过class定位可以使用find_element_by_class_name()函数。
</li>
<li>
通过tag定位使用find_element_by_tag_name()函数。
</li>
<li>
通过link上的完整文本定位使用find_element_by_link_text()函数。
</li>
<li>
通过link上的部分文本定位使用find_element_by_partial_link_text()函数。有时候超链接上的文本很长,我们通过查找部分文本内容就可以定位。
</li>
<li>
通过XPath定位使用find_element_by_xpath()函数。使用XPath定位的通用性比较好因为当id、name、class为多个或者元素没有这些属性值的时候XPath定位可以帮我们完成任务。
</li>
<li>
通过CSS定位使用find_element_by_css_selector()函数。CSS定位也是常用的定位方法相比于XPath来说更简洁。
</li>
在我们获取某个元素之后,就可以对这个元素进行操作了,对元素进行的操作包括:
1. 清空输入框的内容使用clear()函数;
1. 在输入框中输入内容使用send_keys(content)函数传入要输入的文本;
1. 点击按钮使用click()函数,如果元素是个按钮或者链接的时候,可以点击操作;
1. 提交表单使用submit()函数,元素对象为一个表单的时候,可以提交表单;
了解WebDriver元素定位和功能之后我们模拟一下微博的自动登录具体代码如下
```
from selenium import webdriver
import time
browser = webdriver.Chrome()
# 登录微博
def weibo_login(username, password):
# 打开微博登录页
browser.get('https://passport.weibo.cn/signin/login')
browser.implicitly_wait(5)
time.sleep(1)
# 填写登录信息:用户名、密码
browser.find_element_by_id(&quot;loginName&quot;).send_keys(username)
browser.find_element_by_id(&quot;loginPassword&quot;).send_keys(password)
time.sleep(1)
# 点击登录
browser.find_element_by_id(&quot;loginAction&quot;).click()
time.sleep(1)
# 设置用户名、密码
username = 'XXXX'
password = &quot;XXXX&quot;
weibo_login(username, password)
```
需要说明的是你需要填写自己的微博用户名和密码对应username和password
通过HTML标签分析我们能看到id=loginName和id=loginPassword对应着用户名和密码的输入框获取这两个元素之后使用send_keys()设置用户名和密码然后通过id=loginAction找到登录按钮获取该元素使用click()函数点击提交。
这样我们就完成了微博的自动化登录,具体效果如下:
<img src="https://static001.geekbang.org/resource/image/38/71/380827a5713e41896dfe5436a4589471.gif" alt="">
## 微博自动化运营:加关注,写评论,发微博
我们已经基本了解了Selenium WebDriver是如何获取指定元素并且对元素进行操作的。下面我们撰写一下微博自动加关注写评论发微博的功能代码具体模块如下
<img src="https://static001.geekbang.org/resource/image/61/4e/61ed79746527371c7bf1c173355f6c4e.jpg" alt=""><br>
我们刚才完成了weibo_login微博登录模块的编写现在来看下加关注的功能具体代码如下
```
# 添加指定的用户
def add_follow(uid):
browser.get('https://m.weibo.com/u/'+str(uid))
time.sleep(1)
#browser.find_element_by_id(&quot;follow&quot;).click()
follow_button = browser.find_element_by_xpath('//div[@class=&quot;m-add-box m-followBtn&quot;]')
follow_button.click()
time.sleep(1)
# 选择分组
group_button = browser.find_element_by_xpath('//div[@class=&quot;m-btn m-btn-white m-btn-text-black&quot;]')
group_button.click()
time.sleep(1)
# 每天学点心理学UID
uid = '1890826225'
add_follow(uid)
```
这里有两点你需要注意。
第一点是如何找到用户的UID呢
在微博中用户是用UID做唯一标识的。代码中我随机指定了一个UID你也可以指定其他的UID。那么如何获取用户的UID的呢
你可以点击任何一个微博用户查看他的URL链接比如链接是[https://weibo.com/u/5020181423](https://weibo.com/u/5020181423) 那么u后面的数字5020181423即为用户的UID。你也可能遇到[https://weibo.com/ixinli](https://weibo.com/ixinli)每天学点心理学这样的链接情况那么通过查看他的粉丝即可以显示出UID比如这个微博的粉丝链接是[https://weibo.com/1890826225/fans](https://weibo.com/1890826225/fans)那么UID对应的就是1890826225。
第二个需要注意的是使用XPath定位元素定位。
我们如何找到“关注”这个按钮的元素标识呢在Chrome浏览器中在“关注”按钮用鼠标右键点击选择“检查”查看这个元素对应的代码。通过分析你能看到这个元素的div标签中的class属性为m-add-box m-followBtn那么你可以通过find_element_by_xpath(//div[@class=“m-add-box m-followBtn”])获取这个元素。关注之后,程序会弹出选择分组的页面,如下所示。
通过同样的方法你可以查看“取消”这个按钮对应的HTML标签特征然后通过find_element_by_xpath定位使用click()函数提交。这样我们就关注了一个指定的用户。
<img src="https://static001.geekbang.org/resource/image/8e/0a/8ed67303e83dd8e7aee9338802c2cb0a.png" alt=""><br>
接下来,我们继续完成写评论和发微博的模块代码:
```
# 给指定某条微博添加内容
def add_comment(weibo_url, content):
browser.get(weibo_url)
browser.implicitly_wait(5)
content_textarea = browser.find_element_by_css_selector(&quot;textarea.W_input&quot;).clear()
content_textarea = browser.find_element_by_css_selector(&quot;textarea.W_input&quot;).send_keys(content)
time.sleep(2)
comment_button = browser.find_element_by_css_selector(&quot;.W_btn_a&quot;).click()
time.sleep(1)
# 发文字微博
def post_weibo(content):
# 跳转到用户的首页
browser.get('https://weibo.com')
browser.implicitly_wait(5)
# 点击右上角的发布按钮
post_button = browser.find_element_by_css_selector(&quot;[node-type='publish']&quot;).click()
# 在弹出的文本框中输入内容
content_textarea = browser.find_element_by_css_selector(&quot;textarea.W_input&quot;).send_keys(content)
time.sleep(2)
# 点击发布按钮
post_button = browser.find_element_by_css_selector(&quot;[node-type='submit']&quot;).click()
time.sleep(1)
# 给指定的微博写评论
weibo_url = 'https://weibo.com/1890826225/HjjqSahwl'
content = 'Gook Luck!好运已上路!'
# 自动发微博
content = '每天学点心理学'
post_weibo(content)
```
这个环节里,同样也有一些需要说明的地方。
如何找到某条微博的链接呢?你可以在某个用户微博页面中点击时间的链接,这样就可以获取这条微博的链接。
<img src="https://static001.geekbang.org/resource/image/63/a9/633528f33648263152cd92b353030ba9.png" alt=""><br>
如何定位评论区中输入框元素的位置呢?
我们将鼠标移动到评论框中在Chrome浏览器中点击右键“查看”可以看到这个textarea的class是W_input使用find_element_by_css_selector函数进行定位然后通过send_keys设置内容。
最后就是发微博的流程。我们可以观察到点击微博页面的右上角的按钮后会弹出一个发微博的文本框设置好内容点击发送即可。发微博的函数和写评论的代码类似使用find_element_by_css_selector()函数定位通过send_keys()设置内容的设置最后通过click()发送。
上面的代码你可以自己模拟下,在实际运行过程中,你可能会遇到各种情况,比如下面这种情况:
<img src="https://static001.geekbang.org/resource/image/14/04/1453a3253b24aba642b6bf477b5add04.png" alt=""><br>
微博自动化运营是一个系统的工程需要考虑到各种情况比如相同的内容发布需要间隔10分钟以上关注了一个用户之后就无法对他二次关注可以判断是否已经关注过再关注操作因为操作频繁导致需要输入验证码的情况等。
另外,微博自动化运营只是自动化运营的开始,实际上在微信上我们也可以做同样的操作。比如监听微信群的消息,自动发微信等。实际要考虑的问题比微博的要复杂。
## 总结
今天我带你进行了微博自动化运营的实战通过实战你对使用Selenium WebDriver应该更有了解包括如何定位指定的元素对元素进行各种操作等。同时我们使用了implicitly_wait函数以及time.sleep()函数让浏览器和程序等待一段时间,完成数据加载之后再进行后续的操作,这样就避免了数据没有加载完,导致获取不到指定元素的情况。
通过三个模块(加关注、写评论、发微博)的编写,你能了解如何使用工具完成自动化的操作。在实际的过程中,可能会遇到各种复杂情况,这些都需要你在运行过程中慢慢体会。
自动化运营是个细致的活儿,我在之前的加餐文章中也提到过。如果真的想要实现自动化,还需要解决反垃圾的清理问题等,你可以再回顾一下。
<img src="https://static001.geekbang.org/resource/image/33/d5/33ee64c5a434e1a7093594499e9c05d5.png" alt=""><br>
最后留两道题吧。今天我们对微博加关注这一模块编写了代码同样我们也可能会对某个指定用户的UID做取消关注的操作请你使用今天讲的元素定位和操作功能编写相应的代码。
通过今天自动化测试工具的学习,你有怎样的收获和总结呢?
欢迎在评论区与我分享你的答案,也欢迎点击”请朋友读“,把这篇文章分享给你的朋友或者同事,一起实战交流一下。