很久之前用的socket做了爬虫,然后根据response纯人肉解析text。很是费事,现在好了自从有了BeautifulSoup,整个人都好了。
步骤还是很简单:
- 发送请求
- 解析response
-
保存至text文本
成果:
部分截图,爬取了top250
代码:
from bs4 import BeautifulSoup
import requests
urls = ['https://movie.douban.com/top250?start={}&filter='.format(str(i)) for i in range(0, 250, 25)]
def request_for(url):
f = requests.get(url)
soup = BeautifulSoup(f.text, 'lxml')
# 这个是span标签中的title类,通过这样挑选<span title>
# 这样就省去了那么一长串东西
# titles中用这种长的css路径,因为区分中英文
titles = soup.select("#content > div > div.article > ol > li > div > div.info > div.hd > a > span:nth-of-type(1)")
comments = soup.select("span.inq")
scores = soup.select("span.rating_num")
comments_num = soup.select("div.star > span:nth-of-type(4)")
for title, comment, comment_num, score in zip(titles, comments, comments_num, scores):
title_pre = title.get_text()
title_content = title_pre.split('/')[0]
comment_content = comment.get_text()
comment_num_content = comment_num.get_text()
score_comment = score.get_text()
data = {
'title': title_content,
'comment': comment_content,
'comment_num': comment_num_content,
'score': score_comment
}
with open('豆瓣爬取结果.txt', 'a', encoding='utf-8') as f:
f.write(str(data))
f.write('\r\n')
for url in urls:
request_for(url)```
注:我可算是学会在markdown上面贴代码了!!关键就是:
粘贴的时候选择“粘贴纯文本”
在写这个的过程中遇到了一些问题:
1.BeautifulSoup对象创建的时候,这个.text必须要加上,否则会报错
2.select函数的参数不仅仅可以是copy的selector路径,还可以是符合[css选择器](http://beautifulsoup.readthedocs.io/zh_CN/latest/#id41)的语法。我这里是选择某个标签的类名就用“span.inq”,这个含义就是选择符合span的标签的inq类的所有tag
3.在抓取“评价人数”的时候,遇到了这个问题
![可以看到class这个类下面有四个span标签,不巧的是这个评价人没有任何可以供选择的属性](http://upload-images.jianshu.io/upload_images/2582504-d37de4321ba65b1e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
后来查了一下BeautifulSoup的资料,选择class='star'这个标签下的第四个标签,具体写法是
`comments_num = soup.select("div.star > span:nth-of-type(4)")`
注意这个“:nth-of-type(4)”,其中的4就是第四个标签
4.title还有一些信息做了修改,因为也抓到了英文title,所以这么一做就只有中文title了。(写到这里,我突然想到了可以用2的方法来指定第一个title)
##具体写的步骤:
1.先写title,从select贴路径开始,print一下titles看是否符合自己需求,然后可以在路径上修改,减少或增加路径,直到输出的结果符合预期
2.在for循环中增加title,然后看返回的data字典是否符合预期
3.前两步ok的话就再写comment,写score……逐步建立起来,这样遇到的问题各个击破会比较好。
最后,我这个程序格局写的很糟糕,不过不影响把握大致思路