做了一段时间爬虫,主要通过python架构scrapy来抓去结构化的数据,在此做一些总结:
1. html的解析:
常见的思路有两类:
第一类是htmlparser等,通过start_blabla, do_blabla, end_blabla来处理对于不同tag下的内容,个人不太喜欢这种方式,因为如果需要抽取body/content/a/tr/td...这样的内容,得写好多函数,太不简洁了
第二类是scrapy的selector、beautifulsoup;通过findall这样的api查找需要处理的tag以及内容;
selector和beautifulsoup类似,在此只总结beautifulsoup:
beautifulsoup在分析html之后会生成两类对象:tag对象、navigatableString;
对于navigate html树,直接使用soup.tag, tag可以跳过中间的级别直接到需要的tag;tag包含.contents, 可以通过.children迭代遍历;
重要功能来了:查找剖析树soup.find_all()
find_all(name, attrs, recursive, text, limit, **kwargs)
name:给name传递一个值,Beautiful Soup会认为这个值是某个标签的名称。name的值可以是以上介绍的几种方法。
recursive=false。
text:给text指定一个值,用他来搜索strings,而不是搜索tag,虽然text是用来搜索string的,但是也可以和tag混合使用。soup.find_all("a", text="Elsie")
limit:find_all()会返回所有匹配tag或者text的内容,如果你不需要所有的匹配的内容,而是只需要前几个,可以使用limit参数限制。
kwargs:设置标签的属性值,以字典的形式出现,可以传入多个值。soup.find_all(href=re.compile("elsie"), id='link1')
attrs:如果你有一个文档,它有一个标签定义了一个name属性,会怎么样? 你不能使用name为keyword参数,因为Beautiful Soup 已经定义了一个name参数使用。 你也不能用一个Python的保留字例如for作为关键字参数。Beautiful Soup提供了一个特殊的参数attrs,你可以使用它来应付这些情况。attrs是一个字典,用起来就和keyword参数一样。
find():该函数找到匹配的第一个tag返回。
find_next_siblings只会返回第一个匹配的。
find_all_next():该函数使用.next_elements迭代在该标签之后的所有tag和strings,它返回所有匹配的结果,而find_next()值返回第一个匹配的。
print soup.find_all("a", attrs={"class": "sister"}) 这应该能解决60%以上的问题;
2. scrapy的一些总结
整体架构