900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > python3 requests 动态网页post提交数据_Python爬虫三:动态网页爬虫

python3 requests 动态网页post提交数据_Python爬虫三:动态网页爬虫

时间:2021-11-01 03:06:22

相关推荐

python3 requests 动态网页post提交数据_Python爬虫三:动态网页爬虫

1. 利用API爬取数据

有时,使用BeautifulSoup解析和提取数据后,输出结果为空。这是由于网页使用了另一种加载数据的方式——通过API加载数据。API(Application Programming Interface)即应用程序编程接口,也就是网页和服务器交互的途径。

1) Network

开发者工具中的Network记录的是从打开工具到网页加载完毕之间的所有请求。其中,以All开头的一行是请求类型过滤器,可以展示对应类型的请求。爬虫中常用的有All、XHR、Img和Media。

2) XHR

XHR全称XMLHttpRequest,是浏览器内置的对象,使得JavaScript可以发送HTTP请求。

爬取需要的数据时,首先要在XHR的Name栏中找到数据所在的位置(可通过请求名称和数据大小判断),找到目标后点击这条请求,在Preview中查看数据,即可确认。数据有很多,需要按名称逐层展开。

接下来,点击Headers里的General就可以看到API的链接(即Request URL),这就是获取数据的真正链接。但这个链接一般又长又乱,这时可以用requests.get()方法的params参数,以字典的形式传递链接的查询字符串参数,使代码看上去更加简洁明了。利用Convert HTTP Query String to JSON网站,将网址问号后的参数粘贴到input框中,即可得到转换后的字典形式的参数。

例如,爬取QQ音乐《等你下课》的评论,可以将代码写为:

import requests

headers = {

'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'

}

params = {

'g_tk': '5381',

'loginUin': '0',

'hostUin': '0',

'format': 'json',

'inCharset': 'utf8',

'outCharset': 'GB2312',

'notice': '0',

'platform': 'yqq.json',

'needNewCode': '0',

'cid': '205360772',

'reqtype': '2',

'biztype': '1',

'topid': '212877900',

'cmd': '8',

'needmusiccrit': '0',

'pagenum': '0',

'pagesize': '25',

'lasthotcommentid': '',

'domain': '',

'ct': '24',

'cv': '10101010'

}

res = requests.get('https://c./base/fcgi-bin/fcg_global_comment_h5.fcg', headers=headers, params=params)

print(res.text)

用res.text获取到的数据是字符串形式的,而如果是字典或列表的话,会更容易从中提取评论数据。可以用JSON将其转换为字典或列表。

3) JSON

JSON(JavaScript Object Notation)是编程语言之间通用的数据格式。它的本质是一个字符串,建构于两种结构:键值对的集合和值的有序列表,分别对应Python里的字典和列表。它是一种标准,规定了基本数据结构的写法,不同的编程语言拿到后可以解析成自己对应的数据结构。

4) 解析JSON

对于JSON格式的内容,调用json()方法即可对响应内容解码。例如,获取最新的第一条评论内容,可以在上面的代码后续写:

data = res.json()

print(data['comment']['commentlist'][0]['rootcommentcontent'])

5) 获取多页数据

通过对比不同页码的链接参数可以得出其变化规律。

查看第二页评论的请求,可以发现只有pagenum和lasthotcommentid两个参数发生了变化,pagenum从0变成了1,而lasthotcommentid则是上页最后一条评论的commentid。因此,通过修改参数pagenum和lasthotcommentid的值即可获取多页的评论数据。

例如,获取《等你下课》前五页的评论,完整的代码可以写为:

import requests

import time

headers = {

'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'

}

lasthotcommentid = ''

for pagenum in range(5):

params = {

'g_tk': '5381',

'loginUin': '0',

'hostUin': '0',

'format': 'json',

'inCharset': 'utf8',

'outCharset': 'GB2312',

'notice': '0',

'platform': 'yqq.json',

'needNewCode': '0',

'cid': '205360772',

'reqtype': '2',

'biztype': '1',

'topid': '212877900',

'cmd': '8',

'needmusiccrit': '0',

'pagenum': pagenum,

'pagesize': '25',

'lasthotcommentid': lasthotcommentid,

'domain': '',

'ct': '24',

'cv': '10101010'

}

res = requests.get('https://c./base/fcgi-bin/fcg_global_comment_h5.fcg', headers=headers, params=params)

data = res.json()

for item in data['comment']['commentlist']:

print('{}:{}'.format(item['nick'], item['rootcommentcontent']))

lasthotcommentid = data['comment']['commentlist'][-1]['commentid']

time.sleep(1)

总之,根据网站是静态的还是动态的,爬虫的策略有所不同。静态网页使用BeautifulSoup解析网页源代码,动态网页直接找到加载数据的API,从API中爬取数据。

2. cookie

1) 登录账号

在开发者工具中,点击Network,清空请求记录后勾选Preserve log,接下来在网页中输入账号密码登录,即可看到login或signin之类的请求。在这一条请求中,请求方式(Request Method)显示为POST。

2) POST请求

与GET一样,POST也是请求方式的一种。GET用于获取数据,其参数显示在请求地址里;POST用于提交数据,其参数隐藏在Form Data里。可以通过requests.post()来发送POST请求,其参数通过字典的形式传递给data参数。因此,登录账号的操作可以写为:

import requests

headers = {

'user-agent': '……'

}

data = {

'…': '…',

'…': '…'

}

requests.post('登录页面网址', data = data, headers = headers)

在发出POST请求后,服务器会在Response Headers(响应头)中返回一些关于该请求的信息,其中有关登录的信息是set-cookie,其作用是在浏览器中写入cookie,之后的请求中会带上cookie信息。

3) cookie

cookie是浏览器储存在用户电脑上的一小段文本文件,该文件中存了加密后的用户信息、过期时间等,且每次请求都会带上cookie。

4) 发评论

登录成功后,可以用Python做一些只有登录后才能进行的操作。例如,找到一篇文章的评论区,在开发者工具中将请求列表清空,接下来在网页中进行评论操作,即可在请求列表中找到发评论的请求。请求地址在General中,其他参数在Form Data中。

Note:Request请求之间的cookie不共享,需要手动将登录过后的cookie传给发评论的请求。

import requests

headers = {

'user-agent': '……'

}

# 登录参数

login_data = {

'…': '…',

'…': '…'

}

# 评论参数(其中的评论内容可自定义)

comment_data = {

'…': '…',

'…': '…'

}

# 发请求登录

login_req = requests.post('登录地址', data = login_data, headers = headers)

# 将登录后的cookies传递给cookies参数用于发评论请求

comment_req = requests.post('发评论请求地址', cookies = login_req.cookies, data = comment_data, headers = headers)

# 状态码为200表示评论成功

print(comment_req.status_code)

5) session

由于cookie容量有限,难以存储所有的用户信息,因此可以用session建立一份用户档案。cookie中只要存储用户的身份信息,服务器可以通过身份信息来在session中查询用户的其他信息。

可以通过requests.Session()创建一个session,多个请求之间就可以共享cookie了,后续请求便不需要再传cookie参数。此外,也可以通过session.headers.update()方法来更新全局的headers。因此,之前发评论的代码可以改写为:

import requests

headers = {

'user-agent': '……'

}

# 登录参数

login_data = {

'…': '…',

'…': '…'

}

# 评论参数(其中的评论内容可自定义)

comment_data = {

'…': '…',

'…': '…'

}

session = requests.Session()

session.headers.update(headers)

# 使用session登录

login_req = session.post('登录地址', data = login_data)

# 使用session发评论

comment_req = session.post('发评论请求地址', data = comment_data)

# 状态码为200表示评论成功

print(comment_req.status_code)

3. selenium

1) selenium

selenium是浏览器自动化测试框架,可以控制浏览器,模拟人浏览网页,从而获取数据、自动操作等。

可以使用pip install selenium来安装selenium,此外,还需安装相应的浏览器驱动。以Chrome浏览器为例,可打开/mirrors/chromedriver网站,找到对应的浏览器驱动,并下载zip文件。下载完成后将解压的exe放到Python安装目录的Scripts文件夹中。

2) 打开浏览器

用selenium打开Chrome浏览器的代码如下:

from selenium import webdriver

browser = webdriver.Chrome()

运行代码即可打开浏览器,然后将实例化后的浏览器对象赋值给browser变量,就可以操作该对象来控制浏览器。

3) 获取数据

将要打开的网址传给browser对象的get()方法,就可以打开对应的网页,调用quit()可将浏览器关闭。

from selenium import webdriver

browser = webdriver.Chrome()

browser.get('')

browser.quit()

用selenium获取的网页源代码是数据加载完毕后最终的源代码,网页加载后通过API获取的数据也在其中,因此不必区分要爬取的网页是静态网页还是动态网页。

用print(browser.page_source)可以打印出网页源代码。

4) 处理数据

以获取百度首页的div标签为例:

from selenium import webdriver

browser = webdriver.Chrome()

browser.get('')

div = browser.find_element_by_tag_name('div')

print(div.text)

browser.quit()

用selenium查找元素的方法如下:find_element_by_tag_name:通过标签查找元素

find_element_by_class_name:通过class属性名查找元素

find_element_by_id:通过id查找元素

find_element_by_name:通过name属性查找元素

find_element_by_link_text:通过链接文本查找元素

find_element_by_partial_link_text:通过部分链接文本查找元素

通过这些方法得到的返回值都是WebElement对象,它与Tag对象相似,可以获取文本内容和属性值:WebElement.text:获取元素文本内容

WebElement.get_attribute('属性名'):获取元素属性值

上面的方法获取的是第一个符合条件的元素,如果要查找所有符合条件的元素,将方法中的element改为elements即可。

此外,也可以将selenium与BeautifulSoup结合起来,共同完成获取数据和处理数据的工作。例如,获取网页源代码中所有a标签:

soup = BeautifulSoup(browser.page_source, 'html.parser')

a_tags = soup.find_all('a')

for tag in a_tags:

print(tag.text)

browser.quit()

5) 控制浏览器click():点击元素

send_keys():模拟按键输入

通过以上两个方法,在查找到对应的元素后,调用click()方法可以模拟点击该元素,一般用于点击链接或按钮;调用send_keys()方法模拟按键输入,传入要输入的内容即可,一般用于账号密码等输入框的表单填写。

例如,在百度中搜索python并打印搜索结果的标题:

from selenium import webdriver

browser = webdriver.Chrome()

browser.get('')

# 找到搜索框并输入python

search = browser.find_element_by_id('kw')

search.send_keys('python')

# 点击搜索按钮

submit = browser.find_element_by_id('su')

submit.click()

# 找到搜索结果标题

titles = browser.find_element_by_class_name('qnBI_e')

# 打印搜索结果标题

for title in titles:

print(title.text)

browser.quit()

为了提升爬取效率,也可以通过以下代码将浏览器设置为静默模式,让浏览器在后台获取数据、操作页面:

options = webdriver.ChromeOptions()

options.add_argument('--headless')

browser = webdriver.Chrome(options = options)

Reference:

[1] Wes McKinney. . Python for Data Analysis: Data Wrangling with Pandas, NumPy, and IPython, 2nd Edition [M]. O'Reilly Media, Inc.

[2] CSDN博客. Python博客[OL]. /nav/python. .

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。