LinkExtractor的简单使用
在爬取一个网站时,想要爬去的数据同场分布在多个页面中,每个页面包含一部分数据以及通向其他页面的链接;往往想要获取到我们想要的数据,就必须提取链接进行访问,提取链接可使用Selector
和LinkExtractor
两种方法,我们就后一种方法进行简单的使用说明,至于为什么使用LinkExtractor
,当然是因为其在提取大量链接时更加方便。(注:这里所说的爬取是指通过scrapy
框架进行操作的,如果没有当然就需要安装了。)
下载通过一个简单的例子进行演示说明:(这里以起点免费作品页面进行演示)
1 | scrapy shell -s USER_AGENT="Mozilla/5.0" 'https://www.qidian.com/free/all' |
我们以翻页为例,获取它的下一页链接,该页面是这样的:
代码获取一下该翻页链接:1
2
3
4
5from scrapy.linkextractors import LinkExtractor
'div[class="lbf-pagination"]>ul>li:last-child') le = LinkExtractor(restrict_css=
links = le.extract_links(response)
0].url links[
'https://www.qidian.com/free/all?orderId=&vip=hidden&style=1&pageSize=20&siteid=1&pubflag=0&hiddenField=1&page=2'
获取到的url
就是下一页的url
,下面我们就可以完成Spider
的提取下一页链接的任务。
简单创建一个爬虫项目:
1 | $ scrapy startproject qidian |
下面我们开始编写spiders
中的qidianBook.py
,针对这个项目,我们仅仅获取一下所有小说的书名、作者、分类、简介:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from urllib.parse import urljoin
class QidianbookSpider(scrapy.Spider):
name = 'qidianBook'
allowed_domains = ['qidian.com']
start_urls = [
'https://www.qidian.com/free/all?orderId=&vip=hidden&style=1&pageSize=20&siteid=1&pubflag=0&hiddenField=1&page=1'
]
def parse(self, response):
baseUrl = response.url
book_lis = response.xpath('//ul[@class="all-img-list cf"]/li')
for li in book_lis:
book_name = li.xpath('.//h4/a/text()').extract_first()
book_author = li.xpath('.//p[@class="author"]/a[@class="name"]/text()').extract_first()
book_type = '*'.join(li.css('p[class="author"]>a:nth-child(4)::text,a:nth-child(6)::text').extract())
item = {
'书名:': book_name,
'作者:': book_author,
'类型:': book_type,
}
url = li.css('h4>a::attr("href")').extract_first()
complete_url = urljoin(baseUrl, url)
yield scrapy.Request(complete_url, callback=self.get_intro, meta={'item': item})
le = LinkExtractor(restrict_css='div[class="lbf-pagination"]>ul>li:last-child')
links = le.extract_links(response)
if links:
next_url = links[0].url
yield scrapy.Request(next_url, callback=self.parse)
def get_intro(self, response):
item = response.meta['item']
intro = response.css('div[class="book-intro"]>p::text').extract_first().replace(' ', '').replace('\r', '').replace('\u3000', ' ')
item['简介:'] = intro
return item
然后我们执行这个爬虫,执行之前可以在settings
中添加一个USER_AGENT
:1
USER_AGENT = 'Mozilla/5.0 (X11; Ubuntu; Linu…) Gecko/20100101 Firefox/62.0'
执行,并把结果保存到qidian.json
中:1
scrapy crawl qidianBook -o qidian.json -s FEED_EXPORT_ENCODING=utf-8
你可得有心理准备,这一运行,就会把所有书爬下来。
之后你就可以查看qidian.json
文件里的内容了:1
2
3
4
5
6
7
8
9
10 cat qidian.json
[
{"书名:": "神级生灵", "作者:": "魔动", "类型:": "玄幻*东方玄幻", "简介:": " 穿越不是神话,这是龙炅的座右铭,也只是座右铭!"},
{"书名:": "云穹之未来断点", "作者:": "骷髅精灵", "类型:": "科幻*未来世界", "简介:": " 异族入侵太阳系,血狼战队队长莫峰在一场惨烈的会战之后回到了末日之前,他能否解开谜团,改变身边亲人朋友的命运……"},
{"书名:": "最遥远的南边", "作者:": "哦罗罗", "类型:": "现实*成功励志", "简介:": " 几十个英文单词储备就远赴海外,是头脑发热还是......?"},
{"书名:": "保持匿名", "作者:": "莫远遥", "类型:": "现实*现实百态", "简介:": " 突然发现至少20个字的介绍不知该说些什么,其实,连作品类型,我也不确切我选对没有,它当然和“玄幻”“奇幻”“武侠”“仙侠”“军事”“历史”“游戏”“体育”“灵异”“女生”“二次元”这类无关,天,完全不入流的啊,还有谁会看,“科幻”的话,应该也不算,那就只剩下都市和职场了,可是,那些奇人神人离奇幻想狗血剧情,我实在不会啊,也罢也罢,怎么说,小说背景也算是在都市吧,那作品类型就选“都市”吧,可是子类“异术超能”“恩怨情仇”“青春校园”……果然,大家都爱看些充满幻想的东西,算了算了,随意选吧,就当,这里是我一个人的菜园子,每天来浇点水松松土种种菜,也就不求有人问津了。"},
{"书名:": "开天录", "作者:": "血红", "类型:": "玄幻*东方玄幻", "简介:": " 生存,很容易。"},
{"书名:": "红砖街轶事", "作者:": "李安云", "类型:": "现实*现实百态", "简介:": " 一条闹中取静、建筑独特的老街"},
......
]
总结:
LinkExtractor
的使用更方便的获取打了下一页的链接,代码简洁,这仅仅是其一种方式的使用,更多参数请参考Link Extractors