scrapy学习过程中遇到的问题总结
1.scrapy安装
之前安装过pip,所以直接输入 pip install scrapy 就行了,会自动下载好所有需要的组件的
2.创建scrapy项目
scrapy startproject scrapyspider
该命令会自动在当前文件夹下创建scrapyspider的目录
3.启动爬虫命令
scrapy crawl yourspidername
如果后面跟 -o filename.csv 就可以把爬取到的内容以csv格式保存起来
4.爬虫编写
需求:想学爬虫的目标是自动去某个小黄网上搜索最近新出的电影,拿到电影番号,名称,类别等信息,再用番号去bt站点搜索有没有该资源,如果有,再去保存电影的磁力链接,最后保存成csv文件
在实践的过程中遇到了一些非常坑爹的问题,一一记录下来,供参考
1)scrapy教学中的那个网站已经不在了。。。
2)爬取目标网站(小黄网)的时候,报403的错误,也就是禁止访问。这个问题很常见,在网上查了一下,说是切换一个user-agent就行了。然而坑爹的地方来了,都没有说怎么去自定义headers。有人说在设置里设置一下就行了,然后配的图是写在scrapy.cfg里的,我被严重误导了,以为设置的东西都要写在这里,结果怎么都不行。实际上是应该写在setting.py中。
还有另外一种方法,就是写在爬虫内,然后在调用请求的时候,把headers替换成你写的就行了
如下
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
}
headers里不止可以写user-agent,还可以写很多,具体可以写什么,可以打开浏览器的F12,在请求里看一下平时上网浏览网页headers都发送了哪些信息。
也可以写不同的headers以应对不同网页的要求
调用的时候
yield Request(url, headers = self.headers)
这样就可以替换掉headers了
换掉了headers之后,成功访问了网站,并拿到了想要的网页
3)字符编码的问题
拿到番号和电影名称后,迫不及待打开csv文件,结果一看全是乱码。我想到这应该是字符编码的问题。网上查了下说是要以utf-8编码,结果试了不行。后来想到电影名称都是日文,应该用gbk编码,试了下果然成功了
于是重新启动爬虫,结果在爬到第三页的时候,报错了。查了下是因为字符编码的问题,日文中有些符号,没法用gbk编码,但是encode方法,可以追加一个“replace”参数,将无法编码的符号用?代替,或者用“ignore”,忽视无法编码的特殊符号。
添加参数后,成功爬了十页(我控制只爬10页),示例:
item['title'] = movie.xpath('.//div[@class="photo-info"]/span/text()').extract()[0].encode('GBK','replace')
4)xpath的学习
xpath非常简单,也很强大,借助xpath可以很快定位到想要的内容,看10分钟差不多就可以掌握了
5)从一个网页获得item如何将其作为参数传递到另一个请求中
这个问题困扰了我很久。我一开始想的很简单。我首先在一个循环里获得了该页面里所有电影title,番号,和对应的下一级页面的链接,于是我想当然的直接在该循环里request那个链接
yield item
item['movie_detail'] = movie.xpath('.//a/@href').extract()
request = Request(url=item['movie_detail'][0],callback=self.parse_detail, headers=self.headers)
yield request
这是我一开始写的代码,上面那个yield item是保存之前的电影titile之类信息的
然而运行了之后出现了很多错误,得不到想要的结果
对了这里还得提一句,Request请求里,可以填写callback来决定返回的数据由谁来处理,不同结构的页面肯定要不同的方法来处理
我陷入了无尽的麻烦当中,先是查了yield到底是怎么处理函数的,后来了解到yield Request是异步的,所以我实际上传进函数的是循环到最后一次movie_detail[0]
后来又研究到底把yeild放在哪里,然而放在哪里都不对。
此间网上查了很多,又得知,想要传递数据,可以用Request里的meta参数。然而很多人就说了这么一句话,没有例子,也没有详细展开说,具体要怎么用,像我这样的小白真是头都大了。后来在stackoverflow上找到一个好心人写的一个详细的例子,一下子点开了我。
item['movie_detail'] = movie.xpath('.//a/@href').extract()
request = Request(url=item['movie_detail'][0],callback=self.parse_detail, headers=self.headers)
request.meta['item_1'] = item
yield request
像这样可以把item通过meta传递给请求,同时在处理方法中写一个
item_1 = response.meta['item_1']
来接收参数。同理,可以再把item_1传递给item_2等等,这样爬虫就可以带着数据一级一级往下爬了,然后正确的把来自不同页面的数据组合在一起
6)反爬虫
一开始没注意,也没限速,沉浸在爬虫终于正常工作的狂喜之中,结果被bt站点封了ip(喜闻乐见)
常见的一些措施有,准备很多个user-agaent,爬虫工作的时候随机切换;禁止cookie;设置延迟大一点
这些都在setting.py里,而不是在scrapy.cfg里
暂时遇到的问题就这些,当然与我研究的爬虫还很初级有关。下次试试爬爬json的网站。研究爬虫只是因为刚刚看完一些基础的python的语法,想找个东西练练手。在这次的练手过程中收获还是挺大的,果然动手才是学习语言的最好途径。