关于我们
作者:python爱好者、自学ing
个人网站 :到哪儿找导航 欢迎访问!
联系交流:QQ群726693257
背景说明
最近看爬虫教程,讲了豆瓣的爬取,此文作为练习记录。
目标链接:https://www.douban.com/group/EmirKusturica/members?start=35
查看方法:chrome中右键-查看网页源代码
爬取方法:由于目标信息属于存放在html源代码中的静态信息,用scrapy最方便
新建project项目&站点test
新建project和spider
scrapy startproject douban_group
cd douban_group
scrapy genspider douban douban.com
用scrapy shell url进行站点访问测试
scrapy shell https://www.douban.com/group/EmirKusturica/members
报错提示:response 403。表示目标服务器没有正常响应
解决措施:
-
cd 进入该工程文件夹下
-
打开工程文档里的settings.py文件
-
找到DEFAULT_REQUEST_HEADERS,向其中加入Referer、User-Agent两项request参数
代码:
DEFAULT_REQUEST_HEADERS = {
# 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
# 'Accept-Language': 'en',
'Referer': 'https://www.douban.com/group/EmirKusturica/members',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36',
'Cookie': 你自己的浏览器cookie
}
重新输入:
scrapy shell https://www.douban.com/group/EmirKusturica/members
image
其中,response <200 url>表明响应正常,问题解决!
继续:测试元素的xpath提取方法
response.xpath('//div[@class="member-list"]/ul/li/div[@class="name"]/a/text()')
得到理想的返回结果,正确!test测试结束。
文档配置
文档1:settings.py
- 配置DEFAULT_REQUEST_HEADERS,已在前面完成
- 配置ROBOTSTXT_OBEY = False
- 配置IP:这里没有配置
文档2:items.py
该文档中定义需要提取的信息,默认使用scrapy.Item作为父类
这里定义了name 、image_url、homepage_url 和position四个属性
class DoubanGroupItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
name = scrapy.Field()
image_url = scrapy.Field()
homepage_url = scrapy.Field()
position = scrapy.Field()
文档3:douban.py【 spider文件】
前置步骤:
from douban_group.items import DoubanGroupItem
- 错点提示:
- 需要在pycharm中将douban_group这个project项目文件夹设置为Sources Root
否则,import将报错,找不到douban_group.items - project命名不要和python模块重名,如json.py将会和import json冲突
- 需要在pycharm中将douban_group这个project项目文件夹设置为Sources Root
定义该class的属性
name = 'douban'
allowed_domains = ['douban.com']
start_urls = "https://www.douban.com/group/EmirKusturica/members?start="
- 错点提示:
- start_urls中必须是完整的url,其中的https://请求协议不能省略
- 小知识:URL=请求协议(http或https)+ 域名(douban.com或二级域名www.douban.com) + 对象路径(group/EmirKusturica/members?start=**)
定义该class的方法
目标1:返回提取的信息item
items = DoubanGroupItem()
items["name"] = response.xpath("//div[@class='member-list']/ul/li/div[@class='name']/a/text()").extract()
# 错点提示:python的引号使用规则,内单外双、内双外单都可以,但就是不能内双外也双!!!!!!!!!
items["image_url"] = \
response.xpath("//div[@class='member-list']/ul/li/div[@class='pic']/a//img/@src").extract()
items["homepage_url"] = \
response.xpath("//div[@class='member-list']/ul/li/div[@class='name']/a/@href").extract()
if len(response.xpath("//div[@class='member-list']/ul/li/div[@class='name']/span/text()")) > 0:
items["position"] = \
response.xpath("//div[@class='member-list']/ul/li/div[@class='name']/span/text()").extract()
else:
items["position"] = "未知"
print("找到一个位置不详成员!")
yield items
- 错点提示:
- xpath()中的引号使用,详见注释;
- 原网页中存在position信息空缺项目,需要进行if判断;
- 用yield,不要用return,否则该方法后面的代码将被直接忽略
目标2:返回下一次爬取的URL
now_page = response.xpath("//span[@class='thispage']/text()").extract()
print("正在处理第", now_page, "页")
next_page = response.xpath("//span[@class='next']/a/@href").extract()[0]
print("下一页的地址:", next_page)
total = response.xpath("//span[@class='count']/text()").extract()
print("该小组成员总数:", total)
if len(next_page) != 0: # 判断“下一页”标签是否为空
url = next_page
yield scrapy.Request(url, callback=self.parse)
# 这里是“yield scrapy.Request()”命令,而不是“yield url”
# callback=self.parse表示规定下一次的response对象同样用parse方法处理
else:
print("完成,我们已经抵达最后一页啦!")
- 错点提示:
- 这里直接提取“下一页”的href,更加合理
- 返回URL是:yield scrapy.Request()”命令,而不是“yield url”
- 需要指定参数callback=self.parse,规定下一次的response对象如何处理
文档4:pipelines.py
该文档中定义所提取的items信息如何保存,此处暂略
运行scrapy crawl **
- scrapy list :查看并检查spider文件
- scrapy crawl douban -o douban_group_namelist_all.csv
错点提示:这里仅支持保存为csv、json、xml等格式,不支持xls
数据分析应用
后续……
网友评论