爬虫学习笔记
-
Requests基础发送请求
- 所有requests请求均返回response对象
- requests.get(url) 通过get方式发送请求
- 参数可以通过url+?+key=value&…方式添加
- 也可以dict={key:value},requests.get(url,params=dict)方式添加
- requests.post(url) 通过post方式发送请求
- 参数可以通过dict={key:value}, requests.post(url,data=dict)方式添加
- 如果不以表单形式提交,request.post(url,data=json.dumps(dict))
- requests.get(url, headers = headers) 定制请求头
- headers的内容可以审查里查看request header里内容
- requests.get(url,cookies = cookies) 发送cookies到服务器
- cookies = dict(Cookies=’working’) key和value都从request hearder里查看(用于免登陆)
- response.cookies可以获得可用于登陆的cookie,但是只能从post方法的requests得到cookies
- requests.utils.dict_from_cookiejar(cookies) 将cookie转换为dict
- requests.get(url, proxies=proxies) 使用代理
- requests.get(url, timeout=n) n秒后停止等待响应
-
响应内容
- r= requests.get(url)
- r.url 传递的地址
- r.text 文本格式内容
- r.json json格式内容
- r.content 字节格式内容(常用)
- r.status_code 响应状态码
- 正常 200 requests.code.ok
- r.headers 服务器响应头
-
Session
- Session保持用户的登录信息
- s=requests.Session() 新建Session
- s.headers.update({‘x-test’: ‘true’}) 之后的不用在参数里加上headers
- s.post(url,data)得到cookie后,再s.get(url)可以不通过cookie就可以访问页面
-
如何反爬虫
- cookies池,更换cookie意味着更换用户
- proxies池,更换proxy意味着更换IP
- header中伪装浏览器,加入User-Agent及Referer
- 设置延迟,time.sleep(1)
-
正则表达式常用符号
- .:匹配任意字符,换行符\n除外, 类似一个占位符
- *:匹配前一个字符0次或无限次
- ?:匹配前一个字符0次或1次
- +:匹配前一个字符1词或无限次
- .*:贪心算法,能找到多少是多少
- .*?:非贪心算法
- \d:匹配数字
- [abc]:abc任意一个
- {m,n}:匹配前一个字符m到n次
- | :匹配|左右任意一个
- (.*?) :输出符合条件的,将()里结果返回
-
常用方法
- findall:匹配所有符合规律的内容,返回包含结果的列表;
- 第一个参数是pattern,第二个是查找范围
- re.S作为findall的第三个参数,让 . 匹配\n
- 以列表返回将所有的结果
- content = re.findall(r'(.*?)', html, re.S)
- search:匹配并提取第一个符合规律的内容,返回一个正表达式对象
- group(1)表示取出()里面的
- url = re.search(r'', each, re.S).group(1)
- sub:替换符合规律的内容,返回替换后的值
- 第一个参数是pattern,第二个参数替换的值,第三个是替换变量
- test_str = re.sub(u'美元|人民币|元|本金|代理|的', '', test_str)
- findall:匹配所有符合规律的内容,返回包含结果的列表;
-
XPATH
- 不同于正则表达式基于内容,XPATH基于结构
- 使用lxml包
- from lxml import etree selector = etree.HTML(html) selector.xpath('//*[@id="pagelist"]/form/div/text()')[1]
-
BeautifulSoup创建对象
- soup = BeautifulSoup(html) 创建对象
- soup = BeautifulSoup(open(‘index.html’)) 从文件中创建对象
- print soup.prettify() 打印soup对象 格式化输出
-
Tag
- Tag就是HTML里面的标签
- print soup.[Tag] 查找第一个符合要求的标签
- 每个Tag对象都有name和attrs两个属性,attrs可以以dict形式将所有属性打印出来
- print soup.[Tag][key] 得到单独的某个属性值 等价于soup.[Tag].get(‘key’)
- 可以通过soup.[Tag][key]=value 修改值
- 可以通过del soup.p[key]删除值
-
其他对象
- NavigableString对象 soup.p.string 得到标签里面的内容
- BeautifulSoup对象 表示整个文档的内容,也有name和attrs两个属性即 soup.attrs
- Comment 对象 即注释内容,通过type(soup.a.string)==bs.element.Comment判断
-
遍历文件树
- .content 属性可以将tag的子节点以列表的方式输出,通过列表索引获得某个元素
- .children 返回的不是一个list, 通过遍历查看内容
- .descendants 返回tag的所有子孙节点,需要遍历获得内容
- .strints 获得多个内容,需要便利查看
- .sripped_strings 可以去除多余的空格
- .parent 父节点
- .parents 全部父节点,需要遍历
- .next_sibling 属性获取了该节点的下一个兄弟节点,.previous_sibling 则与之相反
- 本节点处在统一级的节点
- 际文档中的tag的 .next_sibling 和 .previous_sibling 属性通常是字符串或空白,因为空白或者换行也可以被视作一个节点
- .next_siblings 和 .previous_siblings 属性可以对当前节点的兄弟节点迭代输出
- .next_element .previous_element 与 .next_sibling .previous_sibling 不同,它并不是针对于兄弟节点,而是在所有节点,不分层次
- .next_elements 和 .previous_elements 的迭代器就可以向前或向后访问文档的解析内容,就好像文档正在被解析一样
-
搜索文件树find_all( name , attrs , recursive , text , **kwargs )
- name 参数 查找名为name的tag, 字符串对象会过滤掉
- 传字符串 print soup.find_all(‘a’) 会查找与字符串完整匹配的内容
- 传正则表达式 soup.find_all(re.compile(“^b”)) 查找b开头的标签
- 传列表 soup.find_all([“a”, “b”]) 会将与列表中任一元素匹配的内容返回
- 传True 可以匹配任何值 查找所有的tag
传方法 如果这个方法返回 True 表示当前元素匹配并且被找到,如果不是则反回 False - def has_class_but_no_id(tag): return tag.has_attr('class') and not tag.has_attr('id')
- keyword参数 如果一个指定名字的参数不是搜索内置的参数名,搜索时会把该参数当作指定名字tag的属性来搜索,如果包含一个名字为 id 的参数,Beautiful Soup会搜索每个tag的”id”属性
- 可以使用多个制定名字的参数同时过滤
- soup.find_all(href=re.compile("elsie"), id='link1')
- 想用 class 过滤,不过 class 是 python 的关键词,这怎么办?加个下划线就可以
- soup.find_all("a", class_="sister")
- 可以通过 find_all() 方法的 attrs 参数定义一个字典参数来搜索包含特殊属性的tag
- data_soup.find_all(attrs={"data-foo": "value"})
- text参数 可以搜搜文档中的字符串内容.与 name 参数的可选值一样, text 参数接受 字符串 , 正则表达式 , 列表, True
- limit参数 limit=n 只返回前n个结果
- recursive 设置recursive=False 则只检查子节点
- 可以使用多个制定名字的参数同时过滤
- name 参数 查找名为name的tag, 字符串对象会过滤掉
-
其他方法
- find( name , attrs , recursive , text , **kwargs ) 直接返回结果而不是列表
- 类似的还有搜索父节点、兄弟节点、旁边节点等等

浙公网安备 33010602011771号