最近我必须执行一项从一个须要登陆的网站上爬取一些网页的操做。它没有我想象中那么简单,所以我决定为它写一个辅助教程。html
在本教程中,咱们将从咱们的bitbucket帐户中爬取一个项目列表。正则表达式
教程中的代码能够从个人 Github 中找到。浏览器
咱们将会按照如下步骤进行:session
提取登陆须要的详细信息post
执行站点登陆学习
爬取所须要的数据测试
在本教程中,我使用了如下包(能够在 requirements.txt 中找到):网站
requestsui
lxmlurl
步骤一:研究该网站
打开登陆页面
进入如下页面 “bitbucket.org/account/signin”。你会看到以下图所示的页面(执行注销,以防你已经登陆)
若是你在学习Python的过程当中碰见了不少疑问和难题,能够加-q-u-n 227 -435-450里面有软件视频资料免费
仔细研究那些咱们须要提取的详细信息,以供登陆之用
在这一部分,咱们会建立一个字典来保存执行登陆的详细信息:
1. 右击 “Username or email” 字段,选择“查看元素”。咱们将使用 “name” 属性为 “username” 的输入框的值。“username”将会是 key 值,咱们的用户名/电子邮箱就是对应的 value 值(在其余的网站上这些 key 值多是 “email”,“ user_name”,“ login”,等等)。
2. 右击 “Password” 字段,选择“查看元素”。在脚本中咱们须要使用 “name” 属性为 “password” 的输入框的值。“password” 将是字典的 key 值,咱们输入的密码将是对应的 value 值(在其余网站key值多是 “userpassword”,“loginpassword”,“pwd”,等等)。
3. 在源代码页面中,查找一个名为 “csrfmiddlewaretoken” 的隐藏输入标签。“csrfmiddlewaretoken” 将是 key 值,而对应的 value 值将是这个隐藏的输入值(在其余网站上这个 value 值多是一个名为 “csrftoken”,“ authenticationtoken” 的隐藏输入值)。列如:“Vy00PE3Ra6aISwKBrPn72SFml00IcUV8”。
最后咱们将会获得一个相似这样的字典:
payload = {
"username": "<USER NAME>",
"password": "<PASSWORD>",
"csrfmiddlewaretoken": "<CSRF_TOKEN>"
}
请记住,这是这个网站的一个具体案例。虽然这个登陆表单很简单,但其余网站可能须要咱们检查浏览器的请求日志,并找到登陆步骤中应该使用的相关的 key 值和 value 值。
步骤2:执行登陆网站
对于这个脚本,咱们只须要导入以下内容:
import requests
from lxml import html
首先,咱们要建立 session 对象。这个对象会容许咱们保存全部的登陆会话请求。
session_requests = requests.session()
第二,咱们要从该网页上提取在登陆时所使用的 csrf 标记。在这个例子中,咱们使用的是 lxml 和 xpath 来提取,咱们也可使用正则表达式或者其余的一些方法来提取这些数据。
login_url = "https://bitbucket.org/account/signin/?next=/"
result = session_requests.get(login_url)
tree = html.fromstring(result.text)
authenticity_token = list(set(tree.xpath("//input[@name='csrfmiddlewaretoken']/@value")))[0]
**更多关于xpath 和lxml的信息能够在这里找到。
接下来,咱们要执行登陆阶段。在这一阶段,咱们发送一个 POST 请求给登陆的 url。咱们使用前面步骤中建立的 payload 做为 data 。也能够为该请求使用一个标题并在该标题中给这个相同的 url 添加一个参照键。
result = session_requests.post(
login_url,
data = payload,
headers = dict(referer=login_url)
)
步骤三:爬取内容
如今,咱们已经登陆成功了,咱们将从 bitbucket dashboard 页面上执行真正的爬取操做。
url = 'https://bitbucket.org/dashboard/overview'
result = session_requests.get(
url,
headers = dict(referer = url)
)
为了测试以上内容,咱们从 bitbucket dashboard 页面上爬取了项目列表。咱们将再次使用 xpath 来查找目标元素,清除新行中的文本和空格并打印出结果。若是一切都运行 OK,输出结果应该是你 bitbucket 帐户中的 buckets / project 列表。
tree = html.fromstring(result.content)
bucket_elems = tree.findall(".//span[@class='repo-name']/")
bucket_names = [bucket.text_content.replace("n", "").strip() for bucket inbucket_elems]
print bucket_names
你也能够经过检查从每一个请求返回的状态代码来验证这些请求结果。它不会老是能让你知道登陆阶段是不是成功的,可是能够用来做为一个验证指标。
例如:
result.ok # 会告诉咱们最后一次请求是否成功
result.status_code # 会返回给咱们最后一次请求的状态
就是这样。