CrawlSpider爬取链家租房网
- 1. 简单说一说自己爬取后的想法
- 2. crawlspider爬虫思路和简单网页分析
-
- 2.1 目标网页
- 2.2 网页分析和爬取的思路
- 3. 主要的爬虫代码
- 4. 当请求过多防止ip被ban的方法
-
- 4.1 设置 ROBOTSTXT_OBEY
- 4.2 设置更换请求头user-agent
- 4.3 设置自己的ip池
- 4.4 设置scrapy框架本身的爬取速度
- 5. 爬取数据库结果
- 6. 总结
1. 简单说一说自己爬取后的想法
爬取链家网的代码,方法,可视化,成果展示在csdn上有很多,有很多都是一次性爬取1w+或者2w+的数据,但是其给出的代码很少涉及反爬的,确实,爬取链家网的数据更换user-agent即可爬取,但是当你爬取的数据超过一定量的时候(自己在第一次实践的时候仅仅只更换了user-agent为反爬,也没有设置大量的请求头random进行更换,我不知道服务器如何进行识别反爬,自己在第一次爬取的时候当爬取了1500条数据左右的时候,自己ip就被ban了,但刚刚再次进行爬取的时候,这次使用了random更换请求头user-agent,没有报错的爬取了2539条数据,我也不知道为什么,但是当你二次爬取的时候依然会出现人机验证的页面)
,后面返回的网页请求(链家网共100页数据)都是失败的,即当打开网页链接的时候出现的页面是人机验证的页面,这就是设置的反爬措施,已经让服务器识别出来,你的ip被ban的情况。我也是小白,希望大家有什么好的反爬措施或者相关的博文链家可以发送给我,我也想学习学习…爬虫真的是一个入门低,上限高的东西
2. crawlspider爬虫思路和简单网页分析
2.1 目标网页
#start_urls = ['https://xa.lianjia.com/zufang/']
# 或
start_urls = ['https://xa.lianjia.com/zufang/pg1/#contentList']
2.2 网页分析和爬取的思路
以下就是链家网的网页,其是使用get请求,url变换,点击下一页来加载网页的信息,因为使用的是crawlspider进行爬取,不需要观察url的变换规律,查看下一页的网页链接在哪里即可
可以看出下一页的链接都封存在ul标签当中,很容易构造请求的Rule
具体的请求分析这里有写到:
使用CrawlSpider半通用化、框架式、批量请求“链家网”西安100页租房网页(两种方法实现rules的跟进和几个xpath分享)
爬取的思路是通过点击每一页当中的房源请求链接,进入具体的房源介绍页面,对页面中的自己想知道的房子信息进行爬取(如下图便是进入具体的房源页面),网页的源码很容易进行分析,这里便步进行具体的分析,建议使用Xpath进行爬取
3. 主要的爬虫代码
spider.py 中的代码:
class LianjiaSpider(CrawlSpider):
name = 'lianjia'
allowed_domains = ['xa.lianjia.com']
#start_urls = ['https://xa.lianjia.com/zufang/']
# 或
start_urls = ['https://xa.lianjia.com/zufang/pg1/#contentList']
# # 设置爬取的速度
# custom_settings = {
# 'DOWNLOAD_DELAY':2
# }
rules = (
Rule(LinkExtractor(restrict_xpaths='//p[@class="content__list--item--title twoline"]//a'), callback='parse_item'),
#Rule(LinkExtractor(restrict_xpaths='//ul[@style="display:hidden"]//a'))
)
def parse_item(self, response):
item = HouseItem()
item['id'] = response.xpath('//i[@class="house_code"]/text()').extract()
item['time'] = ''.join(response.xpath('//div[@class="content__subtitle"]/text()').extract()).strip()
item['name'] = response.xpath('//p[@class="content__title"]/text()').extract_first()
item['price'] = ''.join(response.xpath('//div[@class="content__aside--title"]/span/text()').extract_first()) + ''.join(response.xpath('//div[@class="content__aside--title"]/text()').extract()).strip().split('\n')[0]
item['method'] = ''.join(response.xpath('//div[@class="content__aside--title"]/text()').extract()).strip().split('\n')
item['rentWay'] = ''.join(response.xpath('//ul[@class="content__aside__list"]//text()').extract()).strip().split('\n')[0]
item['size'] = ''.join(response.xpath('//ul[@class="content__aside__list"]//text()').extract()).strip().split('\n')[1]
item['floor'] = ''.join(response.xpath('//ul[@class="content__aside__list"]//text()').extract()).strip().split('\n')[2]
item['url'] = response.url
#item['domain_id'] = response.xpath('//input[@id="sid"]/@value').get()
#item['name'] = response.xpath('//div[@id="name"]').get()
#item['description'] = response.xpath('//div[@id="description"]').get()
return item
# i = {}
# return i
def parse_start_url(self, response):
for i in range(2,101):
url = 'https://xa.lianjia.com/zufang/pg' + str(i+1) + '/#contentList'
yield scrapy.Request(url)
item.py 中的代码:
class HouseItem(Item):
# define the fields for your item here like:
# name = scrapy.Field()
id = Field()
time = Field()
price = Field()
rentWay = Field()
size = Field()
floor = Field()
url = Field()
name = Field()
method = Field()
pipeline.py 中关于数据清洗的代码:
class TextPipeline(object):
def process_item(self, item, spider):
a = item.get('method')
if len(a) > 1:
item['method'] = a[1]
else:
item['method'] = ''
return item
4. 当请求过多防止ip被ban的方法
自己也是小白,以下的方法是自已人为比较有效的方法,有什么不对的地方或者不足的或者更好的方法请大家评论或私信给出
4.1 设置 ROBOTSTXT_OBEY
这是最简单的设置反爬的措施,这是scrapy框架中是否遵循robots协议的设置,在setting.py中进行设置,这因该是每一次使用爬虫必设置的东西:
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
4.2 设置更换请求头user-agent
这是在向下载器发送请求的时候,截获请求,改变请求头的做法,在middlewares.py中进行设置,高效的做法是设置大量的请求头,使用random进行随机切换,代码很简单,但是原理得知道scrapy框架整体运行的原理:
Scrapy项目运行数据流总览 AND 几个重要的组件、中间件分析
设置完以下的代码后,一定要在settings.py中进行相应的开启
class RandomUserAgentMiddleware():
def __init__(self):
self.user_agenrs = [
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)",
"Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
"Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
"Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
"Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
"Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",
"Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5",
"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20",
"Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52",
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
]
def process_request(self,request,spider):
request.headers['User-Agent'] = random.choice(self.user_agenrs)
4.3 设置自己的ip池
这是一个更加高级的反爬措施,用不同的ip进行请求,这个方法更加高效,但其代价也是很大,自己需要购买稳定的ip,因为我自己做了尝试,自己写代码爬取不同的代理网站上免费的ip,其稳定性特别差,根本不可取,网上推荐的免费的ip代理是西刺代理,但最近它封了,网上也有很多爬取其ip的代码,但我感觉不稳定,哎…
当获取到有效的ip地址后,进行相应的设置即可使用,同样也是在middlewares.py中进行设置:
class ProxyMiddleware(object):
def __init__(self):
self.proxy_list = [
'HTTPS://47.104.158.81:80',
'HTTP://47.91.137.211:3128',
'HTTP://123.57.77.187:8118',
'HTTP://112.245.17.202:8080',
'HTTPS://113.121.92.46:9999',
'HTTPS://123.57.61.38:8118',
'HTTP://61.163.32.88:3128',
'HTTP://103.43.17.220:8993',
'HTTPS://175.6.47.165:8080',
'HTTPS://101.200.127.149:3129',
'HTTP://47.114.142.53:80'
]
def process_request(self,request,spider):
ip = random.choice(self.proxy_list)
request.meta['proxy'] = ip
4.4 设置scrapy框架本身的爬取速度
我在查阅资料后知乎这个写的在理:
爬取速度设置
故,在spider.py中添加如下代码便可以设置整体框架爬取的速度:
# 设置爬取的速度,爬取一个item的时间
custom_settings = {
'DOWNLOAD_DELAY':2
}
这是最笨最简单也是最有效的反爬措施,但不足的地方是设置了爬取速度后当爬取大量的数据是,虽然可以通顺的爬取,但所耗费的时间是非常长的。自己在实践后得出,这是设置每一个item的返回时间,即爬取下载存储一个item的时间,以链家网信息为例,每一页网页有33个租房信息,100页公有3300个租房信息,每个租房信息为一个item,那么理论上爬取所有的房源信息会花费6600秒,共1.8333小时,那么当爬取大量的数据的时候那个时间…
5. 爬取数据库结果
一共三页,数据库默认每页最多1000条数据
6. 总结
以上就是自己感觉比叫实用的反爬方法,肯定知道的不多,希望看过的兄弟们可以指出不足的地方,直接评论或者私信给出更好的反爬方法,真心感谢