状态码
1 | import requests |
r.encoding ==文本编码 #12e912==
r.status_code 服务器响应状态码
- 200 成功 //但愿如此
- 3xx 重定向
- 4xx 客户端错误
5xx 服务器错误
了解TCP/IP三次握手
建立起一个TCP连接需要经过 三次握手:
第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主 动关闭连接之前,TCP 连接都将被一直保持下去。
静态网页抓取
定制HTTP
请求头
用Chrome
浏览器访问 https://ithou.cc
按 F12
或者 鼠标右键
→检查
,然后依次 Network
→All
→F5(刷新)
复制上图的 user-agent
里的内容。
1 | headers = { |
1 | # 定制HTTP请求头 |
传递URL
参数
http://httpbin.org 这个网站能测试 HTTP 请求和响应的各种信息,比如 cookie、ip、headers 和登录验证等,且支持 GET、POST 等多种方法,对 web 开发和测试很有帮助。它用 Python + Flask 编写,是一个开源项目。
1 | # 传递URL参数 |
输出:
1 | 200 |
发送POST
请求
遗憾的是,有些请求并不是GET
方法,因为url传递参数时,极不安全,比如账号和密码以GET
方式发送极不安全,比如,https://ithou.cc/getuser=ithou&password=654321
在这个链接里面以GET
方式发送就暴露了用户名和密码。此时应该采用表单式的POST
请求
1 | # 发送POST请求 |
输出
1 | 200 |
设置超时参数
如果不设置,可爱的爬虫可能会失去响应……
为了测试timeout
参数的效果,故设置 timeout=0.001
,可以看到:在0.001秒内,网站 https://ithou.cc
没有给出任何响应,抛了异常。
源码
1 | import requests |
结果
1 | ConnectTimeout: HTTPSConnectionPool(host='ithou.cc', port=443): Max retries exceeded with url: / (Caused by ConnectTimeoutError(<urllib3.connection.VerifiedHTTPSConnection object at 0x000001FB7125C828>, 'Connection to ithou.cc timed out. (connect timeout=0.001)')) |
豆瓣Robots协议
首先可以看下,豆瓣的 Robots协议
链接:https://www.douban.com/robots.txt
1 | User-agent: * |
Disallow
表示不允许爬取的目录。Allow
相反,Allow表示允许爬取的目录。
在谷歌Search Console上测试robots
P.S 由于某些原因,谷歌 暂时无法访问,可以用百度站长工具代替
允许爬取目录
不允许爬取目录:
User-agent: Wandoujia Spider Disallow: /
,这句代码的意思是:豆瓣不允许豌豆荚爬取任何信息
,哈哈哈哈哈哈哈,笑出声~
#Crawl-delay: 5
表示两次下载请求之间应延迟5秒抓取,这样做是为了避免服务器过载
sitemap
表示告诉爬虫,网站地图,以便更好的爬取信息。比如:https://ithou.cc/robots.txt 我博客上的Robots协议
爬取豆瓣电影TOP250
源码
下载: https://github.com/ithou/Cute-Python-Spider
1 | # ! /usr/bin/python |
动态网页抓取(难)
解析真实地址
使用 Chrome浏览器
的 检查 功能虽然可以找到评论区的真实地址,但是此方法仅限于数据量少的情况,一旦评论数众多,此方法就显得黔驴技穷了。
通过Selenium模拟浏览器抓取(难)
1 | from selenium import webdriver |
webdriver
提供了许多寻找网页元素的方法
输入框可以通过 find_element(s)_by_*
方法寻找 name
属性来确定。
单个元素
find_element_by_id
find_element_by_name
find_element_by_xpath
find_element_by_link_text
find_element_by_partial_link_text
find_element_by_tag_name
find_element_by_class_name
find_element_by_css_selector
多个元素
find_elements_by_id
find_elements_by_name
find_elements_by_xpath
find_elements_by_link_text
find_elements_by_partial_link_text
find_elements_by_tag_name
find_elements_by_class_name
find_elements_by_css_selector
比如我想找到下面这个元素:
1 | <input type="text" name="passwd" id="passwd-id" /> |
可以有以下几种方法:
1 | element = driver.find_element_by_id("passwd-id") |
实现利用selenium的webdriver自动打开 www.python.org 并键入数据自动搜索
源码
1 | from selenium import webdriver |
分析、原理
方法 | 作用 | 备注 |
---|---|---|
driver = webdriver.Chrome() | 绑定Chrome浏览器 | |
driver.get("https://www.python.org/") | 打开网页 | |
elem = driver.find_element_by_name('q') | 利用find_element_by_name 找到搜索框 | |
elem.send_keys('python') | 在搜索框键入(Keys)数据 | |
elem.send_keys(Keys.RETURN) | 搜索 | 相当于Enter 键 |
添加User-Agent
User-Agent
用于模拟访问,webdriver也可以添加。
模拟Android访问:
1 | from selenium import webdriver |