British world champion Mark Cavendish (Sky) was unable to take part in the sprint after being involved in a crash on the last bend.
With 400m remaining, Italy’s Filippo Pozzato collided with the Australian Matt Goss, bringing both men down and forcing Cavendish to take evasive action but without apparently injuring himself.
Ventoso pipped Italians Fabio Felline and Giacomo Nizzolo on the line at the end of a flat 166km stage punctuated by occasional rain showers.
A three-man breakaway of Pierre Cazaux, Martin Keizer and Brian Bulgac made a bid to pull away shortly after the departure from Giorgio del Sannio, but the Sky-led peloton managed to keep their advantage below five minutes.
Dutchman Keizer pulled away from his companions with 30km remaining but he was reeled in 17km from the finish.
In the final stages, Spain’s Joaquim Rodriguez – 8sec behind Hesjedal in second place in the overall standings – tried to steal a march on his rivals, but with no success.
Ventoso, 30, claimed his second Giro success after a previous stage win in nearby Fiuggi last year.
Tuesday’s 10th stage is a 186km ride from Civitavecchia to Assisi, which finishes with two short climbs in the closing 3 500m.
Result and standings after the 166km ninth stage of the Giro d’Italia from San Giorgio del Sannio to Frosinone on Monday:
Stage 9 Top 10 Results:
1. Francisco Ventoso (Spain / Movistar) 3 hrs 39 mins 15 secs
2. Fabio Felline (Italy / Androni Giocattoli) same time
3. Giacomo Nizzolo (Italy / RadioShack)
4. Damiano Caruso (Italy / Liquigas)
5. Daniel Schorn (Austria / NetApp)
6. Alexander Kristoff (Norway / Katusha)
7. Ryder Hesjedal (Canada / Garmin)
8. Matthias Braendle (Austria / NetApp)
9. Manuel Belletti (Italy / AG2R)
10. Daryl Impey (South Africa / Orica-GreedEDGE)
Overall standings after Stage 9:
1. Ryder Hesjedal (Canada / Garmin) 36 hrs 02 mins 40 secs
2. Joaquim Rodriguez (Spain / Katusha) +9″
3. Paolo Tiralongo (Italy / Astana) +15″
4. Roman Kreuziger (Czech Republic / Astana) +35″
5. Benat Intxausti (Spain / Movistar)
6. Ivan Basso (Italy / Liquigas) +40″
7. Damiano Caruso (Italy / Liquigas) +45″
8. Dario Cataldo (Italy / Omega Pharma – Quick-Step) +46″
9. Fraenk Schleck (Luxembourg / RadioShack) +48″
10. Eros Capecchi (Italy / Liquigas) +52″