如何将字符串转换为字典:
# 字典推导式
cookies="anonymid=j3jxk555-nrn0wh; _r01_=1; _ga=GA1.2.1274811859.1497951251; _de=BF09EE3A28DED52E6B65F6A4705D973F1383380866D39FF5; [email protected]; depovince=BJ; jebecookies=54f5d0fd-9299-4bb4-801c-eefa4fd3012b|||||; JSESSIONID=abcI6TfWH4N4t_aWJnvdw; ick_login=4be198ce-1f9c-4eab-971d-48abfda70a50; p=0cbee3304bce1ede82a56e901916d0949; first_login_flag=1; ln_hurl=http://hdn.xnimg.cn/photos/hdn421/20171230/1635/main_JQzq_ae7b0000a8791986.jpg; t=79bdd322e760beae79c0b511b8c92a6b9; societyguester=79bdd322e760beae79c0b511b8c92a6b9; id=327550029; xnsid=2ac9a5d8; loginfrom=syshome; ch_id=10016; wp_fold=0"
cookies = {
i.split("=")[0]:i.split("=")[1] for i in cookies.split("; ")}
#字典是无序的
# 列表推导式
self.url_temp = "https://tieba.baidu.com/f?kw=" + tieba_name + "&ie=utf-8&pn={}"
return [self.url_temp.format(i * 50) for i in range(1000)]
requests用法:
tips:response.text 对象中,名词一般是属性,动词一般是方法,需要加括号
byte型数据(字符串前面加b'的),解码时用decode:
例:b'<!DOCTYPE html>\.... </html>\r\n'
response.content.decode()
# requests中解决编解码的方法
response.content.decode()
response.content.decode("gbk")
response.text
import json
json.loads(response.content.decode())
数据提取方法
json数据提取
- json中的字符串都是双引号引起来的
- 如果不是双引号
- eval: 能实现简单的字符串和python类型的转化
- replace: 把单引号替换为双引号
- 如果不是双引号
json.loads()和json.dump()
html_str = parse_url(url)
# json.loads把json字符串转化为python类型(字典)
ret1 = json.loads(html_str)
# json.dumps能够把python类型转化为json字符串
# ensure_ascii=False设置编码, indent=4设置换行缩进,都是为了使数据看起来更美观
# encoding="utf-8" 也是必要的
with open("douban.json","w",encoding="utf-8") as f:
f.write(json.dumps(ret1, ensure_ascii=False, indent=4))
正则表达式
常用正则表达式的方法:
re.compile(编译)
pattern.match(从头找一个)
pattern.search(找一个)
pattern.findall(找所有)
pattern.sub(替换)
使用注意点:
re.findall("a(*?)b","str")
,能够返回括号中的内容,括号前后的内容起到定位和过滤的效果- 原始字符串r,待匹配字符串中有反斜杠的时候,使用r能够忽视反斜杠带来的转义效果
- 点号默认情况匹配不到\n
\s
能够匹配空白字符串,不仅仅包含空格,还有\t \r \n
Xpath 学习
- 使用xpath helper或者是chrome中的copy xpath都是从element中提取的数据,但是爬虫获取的是url对应的响应,往往和elements不一样
- 获取文本
a/text()
获取a下的文本a//text()
获取a下的所有标签中包含的文本//a[text()='下一页']
根据文本选择
- 获取属性
@符号
- /html/head/link/
//ul[@id="detail-list"]
//
- 在xpath开始的时候表示从当前html中任意位置开始选择
li//a
表示li下任何一个标签(用/的话则需要一级一级选择,比较复杂)
示例:
//ul[@id="detail-list"]/li/a[@class='image share-url']/@href
# /@href 用于获取标签中的网页链接
代码中使用xpath
需要用到lxml库
- 使用入门:
- 导入lxml 的 etree 库
from lxml import etree - 利用etree.HTML,将字符串转化为Element对象
- Element对象具有xpath的方法
html = etree.HTML(text)
- 导入lxml 的 etree 库
from lxml import etree
text = ''' <div> <ul>
<li class="item-1"><a>first item</a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-inactive"><a href="link3.html">third item</a></li>
<li class="item-1"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a>
</ul> </div> '''
html = etree.HTML(text)
print(html)
#查看element对象中包含的字符串
print(etree.tostring(html).decode())
#获取class为item-1 li下的a的herf
ret1 = html.xpath("//li[@class='item-1']/a/@href")
#获取class为item-1 li下的a的文本
ret2 = html.xpath("//li[@class='item-1']/a/text()")
#分组,根据li标签进行分组,对每一组继续写xpath
ret3 = html.xpath("//li[@class='item-1']")
print(ret3)
for i in ret3:
item= {
}
item["title"] = i.xpath("./a/text()")[0] if len(i.xpath("./a/text()"))>0 else None
item["href"] = i.xpath("./a/@href")[0] if len( i.xpath("./a/@href"))>0 else None
print(item)
Scrapy
基础概念
- 异步和非阻塞的区别
异步
:调用在发出之后,这个调用就直接返回,不管有无结果[同步异步是过程]
非阻塞
:关注的是程序在等待调用结果(消息,返回值)时的状态,指在不能立刻得到结果之前,该调用不会阻塞当前线程。[阻塞非阻塞是状态,拿到返回值前的状态,就是不用一直等,可以做其他事情]
Scrapy的流程
Scrapy入门使用
- 创建一个scrapy项目
scrapy startproject [项目名]
- 生成一个爬虫
# 需要先进入项目文件下
cd myproject
scrapy genspider [爬虫名] [域名]
# 运行爬虫
scrapy scrawl itcast
- 提取数据
完善spider,使用xpath等方法 - 保存数据
pipeline中保存数据