文章目录

  • 1.蜘蛛侠思路:
  • 2.构造爬虫及代码解读
    • (1)settings.py
    • (2)ganji.py
    • (3)run.py
    • (4)items.py
    • (5)pipelines.py
    • (6)前十条数据
  • 3.蜘蛛侠的小Tips(不是黑丝)

1.蜘蛛侠思路:

赶集网
爬取网站的url地址:点击超链接-----赶集网主页-------

步骤一:开始爬虫的第一步应该是要先明确需要爬取的目标网址,这就需要花一些时间了解网站的大致结构,以及明确自己想要获取的数据,并且需要知道这些数据是通过什么方式展现出来的,这就需要查看网站的源代码,如果网站源代码中没有这些数据,就需要考虑其是否是用ajax等方式发送的。

步骤二:观察切换页码时url地址的规律变化

步骤三:观察详情页url地址的规律变化,编写代码

-点击【切换城市】转到有所有城市的主页

2.构造爬虫及代码解读

你可以通过cmd构建爬虫,也可以直接使用pycharm中自带的终端构建爬虫

#创建爬虫项目
scrapy startproject ganji_crawl#创建爬虫
scrapy genspider ganji anshan.ganji.com

身为一个蜘蛛侠,首先就是需要猥琐,不能让网站知道你是蜘蛛侠,超人都需要隐藏身份,所以我们先写好settings.py文件,把自己伪装成浏览器,让网站不知道我们是蜘蛛侠,然后再写爬虫,以免暴露身份,我把每个文件都分成了单个函数来讲解,这样更方便理解一下,合在一起就是完整的了。

(1)settings.py

爬取一些简单的网站,不需要修改那么多,简单改一下就行了。

LOG_LEVEL='WARNING' #日志的输出等级,不想看那么多日志信息就可以写成WARNINGUSER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'#把自己伪装成浏览器ROBOTSTXT_OBEY = False #不遵从机器人协议#把注释去掉就行
ITEM_PIPELINES = {'erShouFang.pipelines.ErshoufangPipeline': 300,
}

USER_AGENT随便打开一个网站按F12就能找到,不同浏览器的USER_AGENT是不一样的

(2)ganji.py

import scrapy
import re
from ..items import ErshoufangItem
class GanjiSpider(scrapy.Spider):name = 'ganji' #爬虫名,运行的关键参数start_urls = ['http://www.ganji.com/index.htm']def start_requests(self):for urls in self.start_urls:yield scrapy.Request(url=urls,callback=self.parse_province)

通过start_urls 对赶集网主页发起请求。重写 start_requests 方法,一般不直接用parse函数,构造一个新函数会更好;这里通过callback回调了一个新的函数parse_province

 def parse_province(self,response):all_city_href = response.xpath('.//div[@class="all-city"]/dl/dd/a/@href').extract()[:1]  #300个城市中选前1个for city_href in all_city_href:yield scrapy.Request(url=city_href+"zufang",callback=self.parse_detail_urls)

1.定义了一个解析主页所有城市超链接的函数,获取到所有城市的超链接,由于条件有限,这里就只获取第一个url,如果你想一口气干到底,你可以试着把[:1]这个限制去掉… 学到这个思路就好
/
2.extract() 返回的是一个列表extract_first()返回列表第一个元素,get()返回一个字符串
/
3.all_city_href获取到的url是不完整,所以还需要拼接一下才能请求到目标网址
/
4.callback回调函数,通过获取到的url发起新的请求
5.url = http://anshan.ganji.com/zufang/ , zufang=租房,二手房=ershoufang …

通过观察网站,我们发现详情页有我们需要的所有数据,所以这里我直接获取详情页的数据就行了。
我删

    def parse_detail_urls(self,response):print("province_urls:" + response.url)all_detail_url = response.xpath('.//dd[@class="dd-item title"]/a/@href').extract()for detail_url in all_detail_url:if "http" in detail_url:yield scrapy.Request(url=detail_url,callback=self.parse_detail)if "http" not in detail_url:yield scrapy.Request(url="http:"+detail_url,callback=self.parse_detail)next_url = response.xpath('.//a[@class="next"]/@href').get()if next_url:yield scrapy.Request(url=next_url, callback=self.parse_detail_urls)

1.定义一个获取详情页url和实现自动翻页的函数,至于加这个 http 的判断是因为获取的详情页url中有一些是不完整的,所以需要加个判断
2.next_url获取下一页的url地址,通过callback回调自己,实现自动翻页,不需要再去看网站有多少一页,再写个循环了…
3.获取到下一页的url地址,如果这个url存在,就说明有下一页呗。

    def parse_detail(self,response):print("detail_ulrs:"+response.url)item = ErshoufangItem()  #存储item['title'] = response.xpath('normalize-space(.//title/text())').get()item['money']  = response.xpath('.//div[@class="price-wrap"]/span[1]/text()').get()item['ya_type']  = response.xpath('.//div[@class="price-wrap"]/span[2]/text()').get()item['huxing']  = response.xpath('.//ul[@class="er-list f-clear"]/li[1]/span[2]/text()').get()mianji  = response.xpath('.//ul[@class="er-list f-clear"]/li[2]/span[2]/text()').get()item['zu_type']  =re.findall('\w{2}',mianji)[0]item['pingfa']  =re.findall('\w{2}',mianji)[1]item['chaoxiang']  = response.xpath('.//ul[@class="er-list f-clear"]/li[3]/span[2]/text()').get()louceng = response.xpath('.//ul[@class="er-list f-clear"]/li[4]/span[2]/text()').get()item['cengshu']  = re.findall('\d+',louceng)[0]item['zhuangxiu']  = response.xpath('.//ul[@class="er-list f-clear"]/li[5]/span[2]/text()').get()item['xiaoqu']  = response.xpath('.//ul[@class="er-list-two f-clear"]/li[1]/span[2]/a/span/text()').get()item['ditie']  = response.xpath('.//ul[@class="er-list-two f-clear"]/li[2]/div/span/text()').get()item['dizhi']  = response.xpath('normalize-space(.//ul[@class="er-list-two f-clear"]/li[3]/span[2]/text())').get()item['name']  = response.xpath('.//div[@class="user-info-top"]/div[1]/a/text()').get()yield item

1.xpath获取详情页数据就得了,不想多说,逻辑到这里就差不多结束了,剩下的搬砖就行。
2.normalize-space()可以直接去掉\n,\t空格等,就不需要再多写代码去空格了
3.mianji获取到的数据是这样的 “整租 106㎡”,通过正则把他们切分一下,只取数字
4.louceng获取到 “共1层”,通过正则只取数字,到这里就完成了对数据的简单清洗

(3)run.py

from scrapy import cmdline
cmdline.execute('scrapy crawl ganji'.split())

编写运行的类

(4)items.py

需要存储什么就写什么

class ErshoufangItem(scrapy.Item):# define the fields for your item here like:title = scrapy.Field()money = scrapy.Field()ya_type = scrapy.Field()huxing = scrapy.Field()zu_type = scrapy.Field()pingfa = scrapy.Field()chaoxiang = scrapy.Field()cengshu = scrapy.Field()zhuangxiu = scrapy.Field()xiaoqu = scrapy.Field()ditie = scrapy.Field()dizhi = scrapy.Field()name = scrapy.Field()

(5)pipelines.py

class ErshoufangPipeline(object):def __init__(self):# self.connect = pymysql.connect(host='localhost',user='root',passwd='123456',db='ershoufang')# self.cursor = self.connect.cursor()self.file =codecs.open('./zufang.json','w','utf-8')self.dic = ""

1.class ErshoufangPipeline(object):加上(object)
2.self.connect,self.cursor定义mysql数据库连接,可以把数据存储到数据库
3.self.dic = "" 铺垫一下,方便 后面存储为字典

    def process_item(self, item, spider):# sql="""# insert into table(title,money) values(%s,%s)# """# self.cursor.execute(sql,(item['title'],item['money']))# self.connect.commit()  #提交lines = json.dumps(dict(item),ensure_ascii=False)+",\n"self.dic+=lines  return itemdef close_spider(self,spider):self.file.write("[{0}]".format(self.dic[:-2])) self.file.close()# self.connect.close()# self.cursor.close()

1.self.file.write("[{0}]".format(self.dic[:-2])) ,写入文件,这样可以转化为json格式,不然存储的时候会爆红,不是json格式。
2.[:-2] 就是不要最后的两个字符串 “,\n”

(6)前十条数据

[{"title": "红岭家园 2室1厅1卫,鞍千路 - 赶集网", "money": "900", "ya_type": "半年付", "huxing": "2室1厅1卫", "zu_type": "整租", "pingfa": "66", "chaoxiang": "南北", "cengshu": "22", "zhuangxiu": "简单装修", "xiaoqu": "红岭家园", "ditie": "暂无信息", "dizhi": "立山立山广场 - 鞍千路", "name": "696882"},
{"title": "华润置地广场 1室0厅1卫,建国大道,近民生西路 - 赶集网", "money": "1300", "ya_type": "押一付一", "huxing": "1室0厅1卫", "zu_type": "整租", "pingfa": "50", "chaoxiang": "西", "cengshu": "27", "zhuangxiu": "精装修", "xiaoqu": "华润置地广场", "ditie": "暂无信息", "dizhi": "铁东二一九 - 建国大道,近民生西路", "name": "置家"},
{"title": "解放西路52号小区 1室1厅1卫,解放西路52乙号 - 赶集网", "money": "400", "ya_type": "年付", "huxing": "1室1厅1卫", "zu_type": "整租", "pingfa": "40", "chaoxiang": "南北", "cengshu": "6", "zhuangxiu": "简单装修", "xiaoqu": "解放西路52号小区", "ditie": "暂无信息", "dizhi": "铁西九街口 - 解放西路52乙号", "name": "hbjes_au6"},
{"title": "铁东一道街 3室2厅1卫 - 赶集网", "money": "1000", "ya_type": "半年付", "huxing": "3室2厅1卫", "zu_type": "整租", "pingfa": "86", "chaoxiang": "东西", "cengshu": "6", "zhuangxiu": "简单装修", "xiaoqu": null, "ditie": "暂无信息", "dizhi": "铁东站前", "name": "王先生"},
{"title": "调军台小区 1室1厅1卫,鞍千路 - 赶集网", "money": "950", "ya_type": "押一付三", "huxing": "1室1厅1卫", "zu_type": "整租", "pingfa": "55", "chaoxiang": "东南", "cengshu": "17", "zhuangxiu": "精装修", "xiaoqu": "调军台小区", "ditie": "暂无信息", "dizhi": "立山立山广场 - 鞍千路", "name": "吴女士"},
{"title": "烈士山社区 1室1厅1卫,胜利南路26号 - 赶集网", "money": "350", "ya_type": "年付", "huxing": "1室1厅1卫", "zu_type": "整租", "pingfa": "50", "chaoxiang": "西北", "cengshu": "8", "zhuangxiu": "简单装修", "xiaoqu": "烈士山社区(民生东路北)", "ditie": "暂无信息", "dizhi": "铁东二一九 - 胜利南路26号", "name": "蓝眼泪335"},
{"title": "中天社区 3室2厅1卫,铁东二道街 - 赶集网", "money": "1500", "ya_type": "年付", "huxing": "3室2厅1卫", "zu_type": "整租", "pingfa": "15", "chaoxiang": "东南", "cengshu": "6", "zhuangxiu": "精装修", "xiaoqu": "中天社区", "ditie": "暂无信息", "dizhi": "铁东站前 - 铁东二道街", "name": "宁女士"},
{"title": "联盟社区 3室0厅1卫,联盟街11号 - 赶集网", "money": "500", "ya_type": "半年付", "huxing": "3室0厅1卫", "zu_type": "整租", "pingfa": "73", "chaoxiang": "南北", "cengshu": "7", "zhuangxiu": "简单装修", "xiaoqu": "联盟社区", "ditie": "暂无信息", "dizhi": "铁东烈士山 - 联盟街11号", "name": "张女士"},
{"title": "红星小区 2室1厅1卫,红星南街22号 - 赶集网", "money": "375", "ya_type": "押一付三", "huxing": "2室1厅1卫", "zu_type": "整租", "pingfa": "68", "chaoxiang": "南", "cengshu": "6", "zhuangxiu": "简单装修", "xiaoqu": "红星小区", "ditie": "暂无信息", "dizhi": "海城永安路 - 红星南街22号", "name": "杨迎女士"},
{"title": "港丽花园 1室1厅1卫,解放东路150号 - 赶集网", "money": "1200", "ya_type": "半年付", "huxing": "1室1厅1卫", "zu_type": "整租", "pingfa": "38", "chaoxiang": "南", "cengshu": "33", "zhuangxiu": "精装修", "xiaoqu": "港丽花园", "ditie": "暂无信息", "dizhi": "铁东解放路 - 解放东路150号", "name": "女士"},

3.蜘蛛侠的小Tips(不是黑丝)

写爬虫的时候用debug模式是非常方便的,如果你不知道怎么用,下面可能会帮到你,如果你会,那就算我没说,因为我也不是很会。 右键run.py选择debug ;

打个断点,至于在什么地方打,比如我想看all_city_href返回了哪些东西,我可以在它后面写个pass打上断点,就不需要print输出了

1.可以看到很多信息,比如请求的状态啊,url啊,等等等…
2.我们点击text右边的view,可以看到获取的数据(网页源代码)

这只蜘蛛结束了朴实无华的一生,想要练习也可以试着去爬取这个网站的更多城市,二手房、厂房啥的j举一反三,不理解的地方可以一起学习交流。代码不完美的地方请多多谅解,多多指教,多多交流。

scrapy爬虫案例-----赶集网相关推荐

  1. 使用scrapy框架做赶集网爬虫

    使用scrapy框架做赶集网爬虫 一.安装 首先scrapy的安装之前需要安装这个模块:wheel.lxml.Twisted.pywin32,最后在安装scrapy pip install wheel ...

  2. scrapy爬虫之凤凰网热点新闻

    初始化一个scrapy项目 scrapy startproject ifengHotNews 用scrapy初始化一个爬虫项目 import scrapyclass getIfengNews(scra ...

  3. python爬虫解决赶集网扫码获取手机号

    (1)正常的抓取页面: 不需要扫码,需要点击查看的 但是没有这个必要,我们仔细看html代码: 发现里面就已经包含了手机号码:点击查看手机号只是个摆设. (2)需要扫码的一个页面,网址为: http: ...

  4. 有缘网分布式爬虫案例2

    有缘网分布式爬虫案例: 修改 spiders/youyuan.py 在spiders目录下增加youyuan.py文件编写我们的爬虫,使其具有分布式: # -*- coding:utf-8 -*-fr ...

  5. 有缘网分布式爬虫案例

    有缘网分布式爬虫案例 # clone github scrapy-redis源码文件 git clone https://github.com/rolando/scrapy-redis.git# 直接 ...

  6. Scrapy使用——抓取赶集网北京公交信息

    转载自:http://wwwdigger.com/?p=111 关于Scrapy工作过程会在之后添加. 0.相关信息 a)首先要已经完成Scrapy的配置安装(如果没有安装,可以参考Scrapy安装过 ...

  7. Scrapy框架爬虫案例

    Scrapy框架爬虫案例 1 什么是Scrapy 2 Scrapy架构 3 Scrapy架构图 4 案例 4.1爬取职友集中阿里巴巴招聘岗位 4.2 创建Scrapy项目 4.3 定义Item 4.4 ...

  8. Scrapy爬虫及案例剖析

    来自:ytao 由于互联网的极速发展,所有现在的信息处于大量堆积的状态,我们既要向外界获取大量数据,又要在大量数据中过滤无用的数据.针对我们有益的数据需要我们进行指定抓取,从而出现了现在的爬虫技术,通 ...

  9. python scrapy框架爬虫当当图书网

    最近在复习scrapy框架,就随便找了个网站做了一下爬虫,当当网,说实话这种网站还是比较好做爬虫的,我没加代理,也没限速,没写多线程,就直接搞下来了,数据量还是比较可观的.接下来进入正题: 先看一下整 ...

最新文章

  1. 初学rpa的十大经典错误及解决办法_Python3之十大经典错误及其解决办法
  2. JavaScript 里,$ 代表什么?/JQuery是什么语言?/html中用link标签引入css时的中 rel=stylesheet属性?/EL表达式是什么?...
  3. 内存的分配方式有几种? 动态内存的的传递注意事项!
  4. opencv-python教程学习系列2-读取/显示/保存图像
  5. linux修改open files:ulimit、file-max
  6. cocos2d-x android 入门
  7. zendstudio快捷键收录
  8. 跳转,location.href,window.open(),load加载页面,iframe加载页面,兼容相关
  9. SVN工作笔记004---svn查看log提示_offline
  10. Python requests抓取有道翻译 最新版破解js加密
  11. 基于C51控制蜂鸣器
  12. 下载 Chrome插件 crx的教程
  13. 基于python的毕业设计仓库库存管理系统
  14. redirect_uri参数错误
  15. 【协议基础】DNS协议概述DNS抓包分析
  16. 希腊字母渊源、发展及字母的读法
  17. 10激活网页被劫持_新手学习SEO需掌握的10大SEO技能
  18. Android中的自定义View(一)
  19. 【rmzt:动漫俺修罗酷爱主题】
  20. 【腾讯TMQ】MBT探索系列 – PRE/POST 模型在网络接口测试MBT的应用和探索

热门文章

  1. CameraSim – 单反相机在线模拟 [Web]
  2. 通信模型中的光轨建模时需要考虑的约束条件。
  3. 励志用 | ACM-ICPC/CCPC 个人经历总结_楚东方(转)
  4. 如何用origin添加水平的横线
  5. 是android机顶盒怎么用,网络电视机顶盒原来可以这么用,让你安卓系统流畅运行!...
  6. File FilecreateNewFile()和createTempFile()的区别
  7. python给手机发通知_【趣味案例】用Python向手机发送通知
  8. 使用lua开发游戏--love2d教程汇总
  9. VC6应用程序正常初始化(0xc0150002)失败的终极解决方案
  10. gcc, g++ - GNU 工程的 C 和 C++ 编译器 (egcs-1.1.2)