Python3网络爬虫开发实战,Scrapy 爬取新浪微博

前面讲解了 Scrapy 中各个模块基本使用方法以及代理池、Cookies 池。接下来我们以一个反爬比较强的网站新浪微博为例,来实现一下 Scrapy 的大规模爬取。

很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!
QQ群:101677771

1. 本节目标

本次爬取的目标是新浪微博用户的公开基本信息,如用户昵称、头像、用户的关注、粉丝列表以及发布的微博等,这些信息抓取之后保存至 MongoDB。

2. 准备工作

请确保前文所讲的代理池、Cookies 池已经实现并可以正常运行,安装 Scrapy、PyMongo 库,如没有安装可以参考前文内容。

3. 爬取思路

首先我们要实现用户的大规模爬取。这里采用的爬取方式是,以微博的几个大 V 为起始点,爬取他们各自的粉丝和关注列表,然后获取粉丝和关注列表的粉丝和关注列表,以此类推,这样下去就可以实现递归爬取。如果一个用户与其他用户有社交网络上的关联,那他们的信息就会被爬虫抓取到,这样我们就可以做到对所有用户的爬取。通过这种方式,我们可以得到用户的唯一 ID,再根据 ID 获取每个用户发布的微博即可。

4. 爬取分析

这里我们选取的爬取站点是:https://m.weibo.cn,此站点是微博移动端的站点。打开该站点会跳转到登录页面,这是因为主页做了登录限制。不过我们可以直接打开某个用户详情页面,如图 13-32 所示。

图 13-32 个人详情页面

我们在页面最上方可以看到她的关注和粉丝数量。我们点击关注,进入到她的关注列表,如图 13-33 所示。

图 13-33 关注列表

我们打开开发者工具,切换到 XHR 过滤器,一直下拉关注列表,即可看到下方会出现很多 Ajax 请求,这些请求就是获取关注列表的 Ajax 请求,如图 13-34 所示。

图 13-34 请求列表

我们打开第一个 Ajax 请求看一下,发现它的链接为:https://m.weibo.cn/api/container/getIndex?containerid=231051_-_followers_-_1916655407&luicode=10000011&lfid=1005051916655407&featurecode=20000320&type=uid&value=1916655407&page=2,详情如图 13-35 和 13-36 所示。

图 13-35 请求详情

图 13-36 响应结果

请求类型是 GET 类型,返回结果是 JSON 格式,我们将其展开之后即可看到其关注的用户的基本信息。接下来我们只需要构造这个请求的参数。此链接一共有 7 个参数,如图 13-37 所示。

图 13-37 参数信息

其中最主要的参数就是 containerid 和 page。有了这两个参数,我们同样可以获取请求结果。我们可以将接口精简为:https://m.weibo.cn/api/container/getIndex?containerid=231051_-_followers_-_1916655407&page=2,这里的 containerid 的前半部分是固定的,后半部分是用户的 id。所以这里参数就可以构造出来了,只需要修改 containerid 最后的 id 和 page 参数即可获取分页形式的关注列表信息。

利用同样的方法,我们也可以分析用户详情的 Ajax 链接、用户微博列表的 Ajax 链接,如下所示:

 

1

2

3

4

5

6

7

8

# 用户详情 API

user_url = 'https://m.weibo.cn/api/container/getIndex?uid={uid}&type=uid&value={uid}&containerid=100505{uid}'

# 关注列表 API

follow_url = 'https://m.weibo.cn/api/container/getIndex?containerid=231051_-_followers_-_{uid}&page={page}'

# 粉丝列表 API

fan_url = 'https://m.weibo.cn/api/container/getIndex?containerid=231051_-_fans_-_{uid}&page={page}'

# 微博列表 API

weibo_url = 'https://m.weibo.cn/api/container/getIndex?uid={uid}&type=uid&page={page}&containerid=107603{uid}'

此处的 uid 和 page 分别代表用户 ID 和分页页码。

注意,这个 API 可能随着时间的变化或者微博的改版而变化,以实测为准。

我们从几个大 V 开始抓取,抓取他们的粉丝、关注列表、微博信息,然后递归抓取他们的粉丝和关注列表的粉丝、关注列表、微博信息,递归抓取,最后保存微博用户的基本信息、关注和粉丝列表、发布的微博。

我们选择 MongoDB 作为存储的数据库,可以更方便地存储用户的粉丝和关注列表。

5. 新建项目

接下来,我们用 Scrapy 来实现这个抓取过程。首先创建一个项目,命令如下所示:

 

1

scrapy startproject weibo

进入项目中,新建一个 Spider,名为 weibocn,命令如下所示:

 

1

scrapy genspider weibocn m.weibo.cn

我们首先修改 Spider,配置各个 Ajax 的 URL,选取几个大 V,将他们的 ID 赋值成一个列表,实现 start_requests() 方法,也就是依次抓取各个大 V 的个人详情,然后用 parse_user() 进行解析,如下所示:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

from scrapy import Request, Spider

 

class WeiboSpider(Spider):

    name = 'weibocn'

    allowed_domains = ['m.weibo.cn']

    user_url = 'https://m.weibo.cn/api/container/getIndex?uid={uid}&type=uid&value={uid}&containerid=100505{uid}'

    follow_url = 'https://m.weibo.cn/api/container/getIndex?containerid=231051_-_followers_-_{uid}&page={page}'

    fan_url = 'https://m.weibo.cn/api/container/getIndex?containerid=231051_-_fans_-_{uid}&page={page}'

    weibo_url = 'https://m.weibo.cn/api/container/getIndex?uid={uid}&type=uid&page={page}&containerid=107603{uid}'

    start_users = ['3217179555', '1742566624', '2282991915', '1288739185', '3952070245', '5878659096']

 

    def start_requests(self):

        for uid in self.start_users:

            yield Request(self.user_url.format(uid=uid), callback=self.parse_user)

 

    def parse_user(self, response):

        self.logger.debug(response)

 

6. 创建 Item

接下来,我们解析用户的基本信息并生成 Item。这里我们先定义几个 Item,如用户、用户关系、微博的 Item,

<think>嗯,用户想用Scrapy爬取京东商品的用户评论数据。首先,我需要回忆一下京东评论页的结构,通常这些数据可能是动态加载的,通过AJAX请求获取。记得之前处理过类似的AJAX请求,可能需要找到评论的API接口。 用户提供的引用里,引用[2]提到了用Scrapy框架爬取京东评论,其中处理item保存到CSV文件。看来可能需要先分析京东评论的请求URL,找到参数规律。比如,可能涉及到productId、page参数等。 然后,用户需要构造请求,可能需要设置headers,比如User-Agent和Referer,避免被反爬。此外,京东可能有反爬措施,需要适当设置下载延迟或使用代理。 引用[3]中提到了处理API请求的参数,比如num_iid,这可能对应京东的商品ID。所以爬虫的第一步是获取商品的ID,然后构造评论的API请求URL。 接下来,解析返回的数据格式,可能是JSON,需要在爬虫中解析并提取需要的字段,比如昵称、内容、评分、时间、地点等。引用[2]的代码示例中,item包含了这些字段,保存到CSV。 另外,分页处理是关键。需要找到总页数,然后循环发送请求。可能需要在parse方法中处理分页逻辑,递归生成新的请求。 还要注意Scrapy的中间件设置,比如UserAgentMiddleware,随机更换User-Agent,或者使用Rotating proxies来避免IP被封。 测试的时候,可能先用scrapy shell来手动发送请求,确认是否能正确获取数据,再整合到爬虫代码中。如果遇到反爬,可能需要更复杂的处理,比如模拟登录或者使用Selenium,但Scrapy本身更适合处理API请求,所以尽量找到直接调用的接口。 最后,数据存储部分,使用Item Pipeline将数据保存到CSV或数据库。引用[2]中的pipeline示例展示了如何将item写入CSV,需要注意追加模式和header的处理。 总结步骤:分析评论API结构、构造请求、处理分页、解析数据、存储数据、应对反爬措施。需要确保代码的各个部分符合Scrapy的框架结构,比如Spider的编写、Item的定义、Pipeline的配置等。</think>### 分步解答:使用Scrapy爬取京东商品评论数据 #### 一、分析京东评论接口 1. **打开浏览器开发者工具** 进入京东商品页面(如商品ID 100000000123),按F12打开开发者工具,切换到`Network`选项卡,筛选`XHR`类型请求,刷新页面后找到评论接口(通常包含`fetchProductPageComments`关键词)。 2. **解析接口参数** 典型评论接口URL示例: ``` https://club.jd.com/comment/productPageComments.action?productId=100000000123&score=0&sortType=5&page=0&pageSize=10 ``` 参数说明: - `productId`: 商品ID - `page`: 页码(从0开始) - `pageSize`: 每页评论数量 #### 二、创建Scrapy项目 ```bash scrapy startproject jd_comment cd jd_comment scrapy genspider jd_spider club.jd.com ``` #### 三、定义Item(items.py) ```python import scrapy class JdCommentItem(scrapy.Item): nickname = scrapy.Field() # 用户昵称 content = scrapy.Field() # 评论内容 score = scrapy.Field() # 评分 creationTime = scrapy.Field()# 评论时间 location = scrapy.Field() # 用户地区 ``` #### 四、编写爬虫(jd_spider.py) ```python import scrapy import json from jd_comment.items import JdCommentItem class JdSpiderSpider(scrapy.Spider): name = &#39;jd_spider&#39; allowed_domains = [&#39;club.jd.com&#39;] def start_requests(self): product_id = &#39;100000000123&#39; # 替换目标商品ID base_url = &#39;https://club.jd.com/comment/productPageComments.action&#39; # 生成初始请求(第一页) yield scrapy.Request( url=f"{base_url}?productId={product_id}&score=0&sortType=5&page=0&pageSize=10", headers={&#39;Referer&#39;: f&#39;https://item.jd.com/{product_id}.html&#39;}, callback=self.parse ) def parse(self, response): data = json.loads(response.text) comments = data[&#39;comments&#39;] # 解析评论数据 for comment in comments: item = JdCommentItem() item[&#39;nickname&#39;] = comment.get(&#39;nickname&#39;) item[&#39;content&#39;] = comment.get(&#39;content&#39;) item[&#39;score&#39;] = comment.get(&#39;score&#39;) item[&#39;creationTime&#39;] = comment.get(&#39;creationTime&#39;) item[&#39;location&#39;] = comment.get(&#39;userProvince&#39;) yield item # 处理分页(示例仅爬取前5页) current_page = data[&#39;pageIndex&#39;] if current_page < 4: # 京东最多返回前100页 next_page = current_page + 1 yield scrapy.Request( url=response.url.replace(f"page={current_page}", f"page={next_page}"), callback=self.parse, headers={&#39;Referer&#39;: response.url} ) ``` #### 五、配置管道(pipelines.py) ```python import pandas as pd class JdCommentPipeline: def open_spider(self, spider): self.file = open(&#39;jd_comments.csv&#39;, &#39;w&#39;, encoding=&#39;utf-8&#39;) self.file.write(&#39;nickname,content,score,creationTime,location\n&#39;) def process_item(self, item, spider): row = f"{item[&#39;nickname&#39;]},{item[&#39;content&#39;]},{item[&#39;score&#39;]},{item[&#39;creationTime&#39;]},{item[&#39;location&#39;]}\n" self.file.write(row) return item def close_spider(self, spider): self.file.close() ``` #### 六、启用管道(settings.py) ```python ITEM_PIPELINES = { &#39;jd_comment.pipelines.JdCommentPipeline&#39;: 300, } ``` #### 七、运行爬虫 ```bash scrapy crawl jd_spider ``` ### 关键技术点说明 1. **反爬应对策略** - 设置`DOWNLOAD_DELAY = 2`降低请求频率[^2] - 使用随机User-Agent中间件 - 通过`Referer`头部模拟正常访问 2. **数据清洗建议** - 使用正则表达式过滤特殊字符:`re.sub(r&#39;[\n\t]&#39;, &#39;&#39;, content)` - 转换时间格式:`datetime.datetime.fromtimestamp(creationTime/1000)` 3. **扩展优化方向** - 添加代理中间件应对IP封锁 - 使用`Scrapy-Redis`实现分布式爬取 - 对接MySQL数据库存储数据(修改Pipeline) 相关问题
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值