当前位置:网站首页>站点数据收集-Scrapy使用笔记
站点数据收集-Scrapy使用笔记
2022-07-29 10:25:00 【c01dkit】
前言
网站数据收集方法有很多,比如最基础的requests,简单几行就可以获取网页信息。使用selenium模拟网页点击可以绕过很多反爬策略,编写思路也不同于其他的方法。用scrapy框架来做的话可以清楚地进行目标拆分,并利用内置的线程池可以非常高效地获取信息。
本文以scrapy为目标,总结基础的使用方法,以供后续复习。
配置
本地配置好python及pip后,使用pip install scrapy既可以安装scrapy。
基本使用
新建工程
scrapy在使用时,需要在主机命令行里scrapy startproject <projectname>创建一个项目,比如运行scrapy startproject example后生成example文件夹,内容如图所示。

添加目标网站
命令行也会提示进入example目录,并运行scrapy genspider来创建一个spider。比如运行scrapy genspider example_spider example.com,之后会在spiders文件夹下生成一个example_spider.py文件。爬虫的代码就需要写在这个文件内。
GET请求
import scrapy
class ExampleSpiderSpider(scrapy.Spider):
name = 'example_spider'
allowed_domains = ['example.com']
start_urls = ['http://example.com/']
def parse(self, response):
pass
POST请求
import scrapy
class ExampleSpiderSpider(scrapy.Spider):
name = 'example_spider'
allowed_domains = ['example.com']
urls = [
'https://example.com/page/1/',
'https://example.com/page/2/',
]
def start_requests(self):
for target in urls:
#发送'Content-Type':'application/x-www-form-urlencoded'的请求
yield scrapy.FormRequest(
url=url,
formdata={
'arg1':'xxx','arg2':'xxx'},
callback=self.parse,
meta={
'arg1':1,'arg2':2}
)
#发送'Content-Type':'application/json'的请求
yield scrapy.Request(
url=url,
method='POST',
body = json.dumps({
'arg1':'xxx','arg2':'xxx'}),
headers = {
'Content-Type':'application/json'},
callback=self.parse,
meta={
'arg1':1,'arg2':2}
)
def parse(self, response):
pass
需要注意的是:
name是爬虫名字,即spidername,之后运行需要指定这个名字。allowed_domains指定允许爬取的域名,也可以不要。start_urls指定需要爬取哪些网站,运行时会一个一个向这些网站发请求,并将响应传给parse函数。如果需要动态生成目标网站,可以删掉这个start_urls变量,并添加一个start_requests(self)成员函数(需要使用yield scrapy.Request(url = <targetwebsite>, callback=self.parse)作为返回值。爬虫运行时如果发现没有定义start_urls变量,则会调用这个函数。scrapy.Request用于发送GET请求。可以添加一个cb_kwargs参数,它接受一个字典,并可以在parse(self, response, **kwargs)中通过kwargs来获取这个字典,以实现自定义的参数传递。也可以使用meta参数,然后在parse里用response.meta获取传递的字典。scrapy.FormRequest用于发送POST请求,请求体放在formdata中,参数应当都是字符串类型。可以使用meta来进行参数传递(也可以用cb_kwargs? 没有测试)
这里对官方文档作以修改举例:
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
def start_requests(self):
urls = [
'https://quotes.toscrape.com/page/1/',
'https://quotes.toscrape.com/page/2/',
]
for url in urls:
yield scrapy.Request(url=url, callback=self.parse, cb_kwargs={
'this_url':url})
def parse(self, response, **kwargs):
page = response.url.split("/")[-2]
url = kwargs['this_url']
filename = f'quotes-{
page}.html'
with open(filename, 'wb') as f:
f.write(response.body)
self.log(f'Saved file {
filename}')
启动爬取
在最外层的example目录下运行scrapy crawl <spidername>,即可开始爬取。
再以官网文档为例:
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
start_urls = [
'https://quotes.toscrape.com/page/1/',
'https://quotes.toscrape.com/page/2/',
]
def parse(self, response):
for quote in response.css('div.quote'):
yield {
'text': quote.css('span.text::text').get(),
'author': quote.css('small.author::text').get(),
'tags': quote.css('div.tags a.tag::text').getall(),
}
response.css来提取元素,其含义不言自明。也可以通过response.text获取文本信息。
这里的parse函数yield了一个字典,可以在运行时指定保存文件:scrapy crawl <spidername> -O <output.jl>来将其保存到文件中,方便后续处理。jl是jsonline即单行json,可以在python中使用简单的文件逐行遍历配合json来处理。其中-O表示覆盖输出文件,-o表示在输出文件后追加。可以添加-L ERROR来忽略运行时无关紧要的输出。
对公开API继续爬取时,jl有奇效。
边栏推荐
- Explore SQL Server metadata (I)
- Are you familiar with the redis cluster principle of high paid programmers & interview questions series 122? How to ensure the high availability of redis (Part 2): cluster mechanism and principle, clu
- 跟着田老师学实用英语语法(持续更新)
- Where are those test / development programmers in their 30s? a man should be independent at the age of thirty......
- Understanding of Arduino circuit
- [jetson][reprint]pycharm installed on Jetson
- Reasons for the rise of DDD and its relationship with microservices
- Second handshake?? Three waves??
- 使用 RTCGA 临床数据进行生存分析
- Efficient 7 habit learning notes
猜你喜欢

HMS Core Discovery第16期回顾|与虎墩一起,玩转AI新“声”态

Scrape crawler framework

Shell notes (super complete)

为什么要使用markdown进行写作?

Hanyuan high tech Gigabit 2-optical 6-conductor rail managed Industrial Ethernet switch supports X-ring redundant ring network one key ring network switch
![[HFCTF 2021 Final]easyflask](/img/58/8113cafae8aeafcb1c9ad09eefd30f.jpg)
[HFCTF 2021 Final]easyflask

电竞入亚后,腾讯要做下一个“NBA赛事捕手”?

汉源高科千兆2光6电导轨式网管型工业级以太网交换机支持X-Ring冗余环网一键环网交换机

跟着田老师学实用英语语法(持续更新)

Is there any charge for PDF processing? impossible
随机推荐
Vim到底可以配置得多漂亮?
Hanyuan high tech Gigabit 2-optical 6-conductor rail managed Industrial Ethernet switch supports X-ring redundant ring network one key ring network switch
Summer 2022 software innovation laboratory training JDBC
3道软件测试面试题,能全答对的人不到10%!你会几个?
mosquitto_ Sub -f parameter use
[jetson][reprint]pycharm installed on Jetson
[FPGA tutorial case 18] develop low delay open root calculation through ROM
Two MySQL tables with different codes (utf8, utf8mb4) are joined, resulting in index failure
[HFCTF 2021 Final]easyflask
[jetson][转载]jetson上安装pycharm
Are you familiar with the redis cluster principle of high paid programmers & interview questions series 122? How to ensure the high availability of redis (Part 2): cluster mechanism and principle, clu
【日志框架】
98. (cesium chapter) cesium point heat
Research on Android multithreading (4) -- from an interview question
全面、详细的SQL学习指南(MySQL方向)
The purpose of DDD to divide domains, sub domains, core domains, and support domains
电竞入亚后,腾讯要做下一个“NBA赛事捕手”?
What happens when MySQL tables change from compressed tables to ordinary tables
Network picture to local picture - default value or shortcut key
Follow teacher Tian to learn practical English Grammar (continuous update)