Préface
Le contenu principal de cet article : Écrivez le robot d'exploration le plus simple dans les plus brefs délais, qui peut explorer les titres et le contenu des messages du forum.
Public de cet article : Les débutants qui n'ont jamais écrit sur les reptiles.
Démarrage
Préparation
Choses que vous devez préparer : Python, Scrapy, un IDE ou tout autre outil d'édition de texte.
1. Le service technique a étudié et décidé que vous rédigerez le robot.
Créez un répertoire de travail à volonté, puis utilisez la ligne de commande pour créer un projet. Le nom du projet est miao, qui peut être remplacé par le nom de votre choix.
scrapy startproject miao
Ensuite, vous obtiendrez la structure de répertoires suivante créée par scrapy
dans le dossier spiders Créer un python, tel que miao.py, comme script du robot. Le contenu est le suivant :
import scrapy class NgaSpider(scrapy.Spider): name = "NgaSpider" host = "http://bbs.ngacn.cc/" # start_urls是我们准备爬的初始页 start_urls = [ "http://bbs.ngacn.cc/thread.php?fid=406", ] # 这个是解析函数,如果不特别指明的话,scrapy抓回来的页面会由这个函数进行解析。 # 对页面的处理和分析工作都在此进行,这个示例里我们只是简单地把页面内容打印出来。 def parse(self, response): print response.body
2. Essayer ?
Si vous utilisez la ligne de commande, ça y est :
cd miao scrapy crawl NgaSpider
Vous pouvez voir que le reptile a imprimé la première page de votre zone interstellaire. Bien sûr, depuis. il n'y a pas de traitement, donc un mélange de balises html et de scripts js sont imprimés ensemble.
Analyse
Ensuite, nous devons analyser la page que nous venons de capturer, de ce html et js Duili a extrait le titre du message sur cette page. En fait, analyser une page est une tâche laborieuse, et il existe de nombreuses méthodes ici, nous introduisons uniquement XPath.
0. Pourquoi ne pas essayer le XPath magique
Jetez un œil à ce que vous venez de saisir, ou ouvrez la page manuellement avec le navigateur Chrome et appuyez sur F12. Vous pouvez voir la structure des pages. Chaque titre est en fait enveloppé par une telle balise html. Par exemple :
<a href='/read.php?tid=10803874' id='t_tt1_33' class='topic'>[合作模式] 合作模式修改设想</a>
Vous pouvez voir que le href est l'adresse du message (bien sûr l'adresse du forum doit être épelée devant), et le contenu enveloppé dans cette balise est le titre du message .
Nous avons donc utilisé la méthode de positionnement absolu de XPath pour extraire la partie avec class='topic'.
1. Regardez l'effet de XPath
Ajoutez une citation en haut :
from scrapy import Selector
Changez la fonction d'analyse en :
def parse(self, response): selector = Selector(response) # 在此,xpath会将所有class=topic的标签提取出来,当然这是个list # 这个list里的每一个元素都是我们要找的html标签 content_list = selector.xpath("//*[@class='topic']") # 遍历这个list,处理每一个标签 for content in content_list: # 此处解析标签,提取出我们需要的帖子标题。 topic = content.xpath('string(.)').extract_first() print topic # 此处提取出帖子的url地址。 url = self.host + content.xpath('@href').extract_first() print url
Exécutez-le à nouveau et vous pourrez voir les titres et les URL de tous les messages sur la première page de la zone interstellaire de votre forum.
Récursif
Ensuite, nous devons capturer le contenu de chaque message. Vous devez utiliser le rendement de Python ici.
yield Request(url=url, callback=self.parse_topic)
Ici, vous demanderez à Scrapy d'explorer cette URL, puis d'analyser la page analysée à l'aide de la fonction parse_topic spécifiée.
À ce stade, nous devons définir une nouvelle fonction pour analyser le contenu d'une publication.
Le code complet est le suivant :
import scrapy from scrapy import Selector from scrapy import Request class NgaSpider(scrapy.Spider): name = "NgaSpider" host = "http://bbs.ngacn.cc/" # 这个例子中只指定了一个页面作为爬取的起始url # 当然从数据库或者文件或者什么其他地方读取起始url也是可以的 start_urls = [ "http://bbs.ngacn.cc/thread.php?fid=406", ] # 爬虫的入口,可以在此进行一些初始化工作,比如从某个文件或者数据库读入起始url def start_requests(self): for url in self.start_urls: # 此处将起始url加入scrapy的待爬取队列,并指定解析函数 # scrapy会自行调度,并访问该url然后把内容拿回来 yield Request(url=url, callback=self.parse_page) # 版面解析函数,解析一个版面上的帖子的标题和地址 def parse_page(self, response): selector = Selector(response) content_list = selector.xpath("//*[@class='topic']") for content in content_list: topic = content.xpath('string(.)').extract_first() print topic url = self.host + content.xpath('@href').extract_first() print url # 此处,将解析出的帖子地址加入待爬取队列,并指定解析函数 yield Request(url=url, callback=self.parse_topic) # 可以在此处解析翻页信息,从而实现爬取版区的多个页面 # 帖子的解析函数,解析一个帖子的每一楼的内容 def parse_topic(self, response): selector = Selector(response) content_list = selector.xpath("//*[@class='postcontent ubbcode']") for content in content_list: content = content.xpath('string(.)').extract_first() print content # 可以在此处解析翻页信息,从而实现爬取帖子的多个页面
Jusqu'à présent, ce robot peut explorer les titres de tous les messages de la première page de votre forum et explorer la première page de chaque message. . contenu à chaque étage. Le principe de l'exploration de plusieurs pages est le même : faites simplement attention à l'analyse de l'adresse URL de la page, à la définition de la condition de fin et à la spécification de la fonction d'analyse de la page correspondante.
Pipelines - Pipelines
Voici le traitement du contenu analysé et analysé, vous pouvez écrire dans des fichiers locaux et des bases de données via des tuyaux.
0. Définir un élément
Créez un fichier items.py dans le dossier miao.
from scrapy import Item, Field class TopicItem(Item): url = Field() title = Field() author = Field() class ContentItem(Item): url = Field() content = Field() author = Field()
Ici, nous définissons deux classes simples pour décrire les résultats de notre exploration.
1. Écrivez une méthode de traitement
Trouvez le fichier pipelines.py sous le dossier miao qui aurait dû être généré automatiquement auparavant.
Nous pouvons construire ici une méthode de traitement.
class FilePipeline(object): ## 爬虫的分析结果都会由scrapy交给此函数处理 def process_item(self, item, spider): if isinstance(item, TopicItem): ## 在此可进行文件写入、数据库写入等操作 pass if isinstance(item, ContentItem): ## 在此可进行文件写入、数据库写入等操作 pass ## ... return item
2. Appelez cette méthode de traitement dans le robot.
Pour appeler cette méthode, il suffit de l'appeler dans le robot. Par exemple, la fonction de traitement de contenu d'origine peut être modifiée en :
def parse_topic(self, response): selector = Selector(response) content_list = selector.xpath("//*[@class='postcontent ubbcode']") for content in content_list: content = content.xpath('string(.)').extract_first() ## 以上是原内容 ## 创建个ContentItem对象把我们爬取的东西放进去 item = ContentItem() item["url"] = response.url item["content"] = content item["author"] = "" ## 略 ## 这样调用就可以了 ## scrapy会把这个item交给我们刚刚写的FilePipeline来处理 yield item
3. le pipeline du fichier de configuration
Trouvez le fichier settings.py et ajoutez-y
ITEM_PIPELINES = { 'miao.pipelines.FilePipeline': 400, }
pour l'appeler dans le robot
"
yield item
sera traité par ce FilePipeline. Le nombre suivant 400 représente la priorité.
Vous pouvez configurer plusieurs pipelines ici. Scrapy remettra les éléments à chaque élément tour à tour en fonction de la priorité, et le résultat de chaque traitement sera transmis au pipeline suivant pour traitement.
Vous pouvez configurer plusieurs pipelines comme ceci :
ITEM_PIPELINES = { 'miao.pipelines.Pipeline00': 400, 'miao.pipelines.Pipeline01': 401, 'miao.pipelines.Pipeline02': 402, 'miao.pipelines.Pipeline03': 403, ## ... }
Middleware——Middleware
Grâce au Middleware, nous pouvons apporter certaines modifications aux informations de la demande. Par exemple, les paramètres couramment utilisés tels que l'UA, le proxy, les informations de connexion, etc. peuvent être configurés via le Middleware.
0.La configuration du Middleware
est similaire à la configuration du pipeline. Ajoutez le nom du Middleware à settings.py, tel que
DOWNLOADER_MIDDLEWARES = { "miao.middleware.UserAgentMiddleware": 401, "miao.middleware.ProxyMiddleware": 402, }
. 1. Cassé le site Web pour vérifier UA, je veux changer d'UA
某些网站不带UA是不让访问的。在miao文件夹下面建立一个middleware.py
import random agents = [ "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.0 Safari/532.5", "Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US) AppleWebKit/532.9 (KHTML, like Gecko) Chrome/5.0.310.0 Safari/532.9", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.514.0 Safari/534.7", "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Chrome/9.0.601.0 Safari/534.14", "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Chrome/10.0.601.0 Safari/534.14", "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.20 (KHTML, like Gecko) Chrome/11.0.672.2 Safari/534.20", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.27 (KHTML, like Gecko) Chrome/12.0.712.0 Safari/534.27", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.24 Safari/535.1", ] class UserAgentMiddleware(object): def process_request(self, request, spider): agent = random.choice(agents) request.headers["User-Agent"] = agent
这里就是一个简单的随机更换UA的中间件,agents的内容可以自行扩充。
2.破网站封IP,我要用代理
比如本地127.0.0.1开启了一个8123端口的代理,同样可以通过中间件配置让爬虫通过这个代理来对目标网站进行爬取。同样在middleware.py中加入:
class ProxyMiddleware(object): def process_request(self, request, spider): # 此处填写你自己的代理 # 如果是买的代理的话可以去用API获取代理列表然后随机选择一个 proxy = "http://127.0.0.1:8123" request.meta["proxy"] = proxy
很多网站会对访问次数进行限制,如果访问频率过高的话会临时禁封IP。如果需要的话可以从网上购买IP,一般服务商会提供一个API来获取当前可用的IP池,选一个填到这里就好。
一些常用配置
在settings.py中的一些常用配置
# 间隔时间,单位秒。指明scrapy每两个请求之间的间隔。 DOWNLOAD_DELAY = 5 # 当访问异常时是否进行重试 RETRY_ENABLED = True # 当遇到以下http状态码时进行重试 RETRY_HTTP_CODES = [500, 502, 503, 504, 400, 403, 404, 408] # 重试次数 RETRY_TIMES = 5 # Pipeline的并发数。同时最多可以有多少个Pipeline来处理item CONCURRENT_ITEMS = 200 # 并发请求的最大数 CONCURRENT_REQUESTS = 100 # 对一个网站的最大并发数 CONCURRENT_REQUESTS_PER_DOMAIN = 50 # 对一个IP的最大并发数 CONCURRENT_REQUESTS_PER_IP = 50
如果非要用Pycharm作为开发调试工具的话可以在运行配置里进行如下配置:
Configuration页面:
Script填你的scrapy的cmdline.py路径,比如我的是
/usr/local/lib/python2.7/dist-packages/scrapy/cmdline.py
然后在Scrpit parameters中填爬虫的名字,本例中即为:
crawl NgaSpider
最后是Working diretory,找到你的settings.py文件,填这个文件所在的目录。
示例:
按小绿箭头就可以愉快地调试了。