问题的由来
前几天,在微信公众号(Python爬虫及算法)上有个人问了笔者一个问题,如何利用爬虫来实现如下的需求,需要爬取的网页如下(网址为:https://www.wikidata.org/w/index.php?title=Special:WhatLinksHere/Q5&limit=500&from=0):

我们的需求为爬取红色框框内的名人(有500条记录,图片只展示了一部分)的 名字以及其介绍,关于其介绍,点击该名人的名字即可,如下图:

这就意味着我们需要爬取500个这样的页面,即500个HTTP请求(暂且这么认为吧),然后需要提取这些网页中的名字和描述,当然有些不是名人,也没有描述,我们可以跳过。最后,这些网页的网址在第一页中的名人后面可以找到,如George Washington的网页后缀为Q23.
爬虫的需求大概就是这样。
爬虫的N中姿势
在settings.py中设置“ROBOTSTXT_OBEY = False”. 修改items.py,代码如下:
# -*- coding: utf-8 -*- import scrapy class WikidatascrapyItem(scrapy.Item): # define the fields for your item here like: name = scrapy.Field() desc = scrapy.Field()然后,在spiders文件夹下新建wikiSpider.py,代码如下:
import scrapy.cmdline from wikiDataScrapy.items import WikidatascrapyItem import requests from bs4 import BeautifulSoup # 获取请求的500个网址,用requests+BeautifulSoup搞定 def get_urls(): url = "http://www.wikidata.org/w/index.php?title=Special:WhatLinksHere/Q5&limit=500&from=0" # 请求头部 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'} # 发送HTTP请求 req = requests.get(url, headers=headers) # 解析网页 soup = BeautifulSoup(req.text, "lxml") # 找到name和Description所在的记录 human_list = soup.find(id='mw-whatlinkshere-list')('li') urls = [] # 获取网址 for human in human_list: url = human.find('a')['href'] urls.append('https://www.wikidata.org' + url) # print(urls) return urls # 使用scrapy框架爬取 class bookSpider(scrapy.Spider): name = 'wikiScrapy' # 爬虫名称 start_urls = get_urls() # 需要爬取的500个网址 def parse(self, response): item = WikidatascrapyItem() # name and description item['name'] = response.css('span.wikibase-title-label').xpath('text()').extract_first() item['desc'] = response.css('span.wikibase-descriptionview-text').xpath('text()').extract_first() yield item # 执行该爬虫,并转化为csv文件 scrapy.cmdline.execute(['scrapy', 'crawl', 'wikiScrapy', '-o', 'wiki.csv', '-t', 'csv'])输出结果如下(只包含最后的Scrapy信息总结部分):
{'downloader/request_bytes': 166187, 'downloader/request_count': 500, 'downloader/request_method_count/GET': 500, 'downloader/response_bytes':
