抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

之前没有系统对爬虫相关的东西学习过, 边看视频边做个笔记.

request / response

request是浏览器/程序向服务器发出的一些信息, 用于请求需要展示的内容, resoponse则是服务器对接收到的请求给出的回应信息.

  • request的内容信息

    • 请求方式: GET / POST(最常用)
      • POST相对GET多了form data
      • GET的参数直接包含在URL中, 而POST请求则包含在表单中
    • 请求URL: URL是统一资源定位符, 就是文件/对象的链接
    • 请求头: 重要的配置信息, 以键值对方式存储
    • 请求体: GET时一般无信息, POST需要
  • response的内容信息

    • 响应状态码: 用来表示请求情况的数字代码
    • 响应头
    • 相应体: 请求的结果

python request模块使用

requests基于urllb3, 使用更方便功能更丰富

GET请求相关

请求参数添加

  • params参数可以方便的给请求增加参数, 省去手动编写URL
1
2
3
4
5
data = {
'arg1': '1',
'arg2': '2'
}
response = request.get('url', params=data)

json解析

  • 提供了json方法, 可直接把返回的json字符串变成json对象
1
2
response = request.get('url', params=data)
response.json()

二进制数据获取

  • 使用get请求直接请求图片即可, 然后写入的时候以’wb’形式写入文件即可

添加header

  • 主要是为了保证获取成功, 有些网站会识别User-Agent以防止机器爬取
1
2
3
4
headers = {
'User-Agent': 'XXXX'
}
response = requests.get('url', headers = headers)

POST请求相关

请求参数 / 头添加

  • 同GET部分(见上)

response属性

  • 常用属性包括:
    • status_code
    • headers
    • cookies
    • url
    • history

状态码分析

  • requests库本身内置了状态码的分类情况, 所以直接调用内置的信息就可以快速判断请求是否正常/成功, 比如response.status_code.ok就相当于200
1
2
response = requests.get('url')
exit() if response.status_code != response.status_code.ok else print('All Right')

代理设置

1
2
3
4
5
6
proxy = {
'http': 'http://127.0.0.1:9743'
'https': 'https://user:passwd@127.0.0.1:9743'
}

response = requests.get('url', proxies=proxy)

如果要使用ss, 则需要另外安装插件

1
pip install 'requests[socks]'
1
2
3
4
5
proxy = {
'socks5': 'http://127.0.0.1:9743'
}

response = requests.get('url', proxies=proxy)

超时设置

可以结合try进行异常处理

1
response = requests.get('url', timeout = 1)

Selenium部分

对于通过js获取数据并进行渲染展示的内容, 在分析页面请求的时候可能会有些东西找不到. 此时可以通过Selenium控制浏览器来进行操作. 虽然这样的效率不高, 但是对于我这种对Web相关的东西不熟的人来说非常适用.

元素查找

模拟网页操作首先要找到需要操作元素的位置, Selenium提供了多种元素定位的方式, 当使用的是find_elememt会返回第一个找到的符合要求的元素, 而使用find_elememts则会以列表返回所有对象

1
2
3
4
5
6
7
8
9
10
browser = webdriver.Firefox()
browser.get('url')
browser.find_element_by_id('123')
browser.find_element_by_name('123')
browser.find_element_by_xpath('123')
browser.find_element_by_link_text('123')
browser.find_element_by_partial_link_text('123')
browser.find_element_by_tag_name('123')
browser.find_element_by_class_name('123')
browser.find_element_by_css_selector('123')

iframe定位

一个网页可能是分了好几块的, 大的框架中可能内嵌了一个或多个iframe, 当位于大框架中时, 是无法搜索/定位小框架内的内容的, 也就无法进行相应操作, 因此需要在操作前进行框切换

1
2
3
4
5
6
7
browser = webdriver.Firefox()
browser.get('url')
# 根据名称切换到iframe
browser.switch_to.frame('analyzeFrame')
# 切换回主框架
browser.switch_to.default_content()
# 没有测试在iframe内是否可切换到其他iframe

弹窗操作

有时候部分操作会弹出一个警示框, 需要切换到这个框进行相应操作, 然后才能继续后续步骤

1
2
3
4
# 切换到弹窗
al = browser.switch_to_alert()
# 点击窗口的接受
al.accpet()

浏览器设置变更

有时需要对浏览器进行特殊设置后才能完成所需操作, 比如我某次爬取的数据可以通过点击一个下载按钮获得, 但是正常情况下点击下载按钮浏览器会弹出下载窗口并

1
2
3
4
5
6
7
8
options = Options()
# 前面一项是设置项名称, 后面的是对应值, 可设置的项目可以浏览器输入'about:config'查看
options.set_preference("browser.download.folderList", 2)
browser = webdriver.Firefox(firefox_options=options)
# 下面这个是设置使用socks代理
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--proxy-server=socks5://localhost:1080')
browser = webdriver.Chrome(chrome_options=chrome_options)

等待设定

Selenium的所有操作会在页面加载完成之后才进行, 但是由于网络的问题, 如果等到加载完毕再执行非常影响效率(Selenium与纯靠代码发送请求的方式相比本来就比较没效率了), 所以可以通过一些设定在满足特定条件后立即执行相关操作. 比如下面就是等待一个特定的搜索按钮可以点击后, 再输入搜索内容并点击搜索.

1
2
3
button = wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'search-bar-btn')))
browser.find_element_by_class_name('search-input').send_keys(tar)
button.click()

下载文件检查

Selenium本身并不能完成下载文件的管理, 因此只能通过别的方式来进行下载文件管理/重命名.

  • 对于可以通过网页代码解析出下载链接的, 可以通过调用别的工具进行下载
  • 对于解析不出下载链接的, 可以通过os模块的相关内容监视下载文件, 并在下载后进行移动及重命名
  • 我当时使用的是下面俩部分代码加起来的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import os
# 抄来的一段代码, 这个函数每隔5s时间检查文件的大小情况, 如果大小跟上一次检查时没有变化, 则判定下载完毕, 会关闭浏览器对象
def wait_download(file_path, browser, rep_name):
current_size = getSize(file_path)
print("{} Downloading".format(str(current_size)))
while current_size != getSize(file_path) or getSize(file_path)==0:
current_size =getSize(file_path)
print("current_size:"+str(current_size))
time.sleep(5)# wait download
print("Downloaded")
os.rename(file_path, rep_name)
browser.close()

# 因为下载启动本身需要时间, 目标文件出现后才启动上面的函数
while not os.path.exists(file_path):
print('waiting for download to start...')
time.sleep(5)
wait_download(file_path, browser, rep_name)

关于模拟点击的坑

Selenium可以模拟对按钮, 链接, 复选框等的点击, 但是点击的前提是, 这些元素必须处于可见范围, 否则点击会无效或者会抛出异常. 因此, 在实际操作时, 需要自己测试一下是否要滚动页面, 以及滚动多少能保证元素可以被点击得到.

1
2
3
4
5
6
# 切出iframe
browser.switch_to.default_content()
# 滚动浏览器到底部
browser.execute_script("window.scrollTo(0,document.body.scrollHeight)")
# 切回iframe
browser.switch_to.frame('analyzeFrame')

杂项

  • 一般第一个get请求得到的是网页的框架, 然后解析框架时再发出新的请求把需要的内容填充到页面
  • 如果需要获得相应信息需要分析ajax请求
    • Selenium/WebDriver
    • Splash

评论

留下友善的评论吧~